alabama
Offline
Full Member
Karma: 1
Posts: 168
|
 |
« on: April 23, 2012, 10:04:41 pm » |
For people who actually know how to code this will seem simple, but no matter what I try I can not get an if statement, while loop, or for loop to work inside of a switch case statement. Do I need to use a bunch of if statements instead, or put switch cases inside fewer ifs and whiles? I am trying to build an Arduino based leveling system for my 5th wheel based on the LevelEasy commercial project, but with some improvements when finished. I built one with mercury switches, SRCs, and relays that works well but requires more user interaction than i like. I figure I have about 300 hours trying to program it and just can't get it.The mechanical and electrical parts all check out, I have o-scopes, function generators, and years of hobby experience for that, just can't get this thing to check a switch or variable when it is in a switch case, and then change actions accordingly. I thought a switch case was just a neater way of having a bunch of if statements, but I can't find an example of one with any other control statements inside it. Is this not possible? Thanks a sample function with problem void memSet() {
lcd_key = read_LCD_buttons(); // read the buttons
switch (lcd_key) // depending on which button was pushed, we perform an action { case btnHITCH:
{ hitchVHigh = average; //Get the upper height to set hitchDifference }
break;
case btnLEVEL: { EEPROM.write((average / 4),1); // save level value to eeprom } break;
case btnTRAVEL: { hitchVLow = average; //get lower hitched value hitchDifference = hitchVHigh - hitchVLow; //calculate hitch offset EEPROM.write(hitchDifference,12); //write offset to eeprom
} break;
}
}
|
|
|
|
|
Logged
|
Einstein once said you don't really understand anything until you can explain it to your Grandmother
|
|
|
|
alabama
Offline
Full Member
Karma: 1
Posts: 168
|
 |
« Reply #1 on: April 23, 2012, 10:44:46 pm » |
And another, the first one won't write to eeprom, this one ignores the pin or variable values. lcd_key = read_LCD_buttons(); // read the buttons
switch (lcd_key) // depending on which button was pushed, we perform an action { case btnHITCH:
{ if (average < unHooked) { lcd.setCursor(0,0); lcd.print(" HITCH "); digitalWrite(upoutpin, HIGH); } }
break;
case btnUP: {
lcd.setCursor(0,0); lcd.print(" MANUAL RAISE "); digitalWrite(upoutpin, HIGH); //raise front of trailer manually
} break;
case btnDOWN: { if (digitalRead(legsw == HIGH)) { lcd.setCursor(0,0); lcd.print("MANUAL LOWER "); digitalWrite(downoutpin, HIGH); } } break;
case btnLEVEL: // function here to save level value and/or level trailer {
if (resetEeprom == LOW) // check for reset sw { EEPROM.write (average,1); //store the level value in eeprom } else {
if (digitalRead(legsw == HIGH && average != (levelVal *4 ))) { if(average > (levelVal *4)) { digitalWrite (downoutpin, HIGH ); lcd.setCursor(0,0); lcd.print(" LEVELING "); } else { digitalWrite(upoutpin, HIGH); lcd.setCursor(0,0); lcd.print(" LEVELING "); } } } break; }
case btnTRAVEL: { if (digitalRead(legsw == HIGH)) { digitalWrite(downoutpin, HIGH); lcd.setCursor(0,0); lcd.print("RAISING LEGS "); //Need limit sw to turn off } break;
} case btnNONE: {
lcd.setCursor(0,0); lcd.print(" NONE "); digitalWrite(upoutpin, LOW); digitalWrite(downoutpin, LOW); } break; }
// delay before next reading: //delay(100); }
}
|
|
|
|
|
Logged
|
Einstein once said you don't really understand anything until you can explain it to your Grandmother
|
|
|
|
West Des Moines, Iowa USA
Offline
Sr. Member
Karma: 2
Posts: 429
|
 |
« Reply #2 on: April 23, 2012, 11:02:38 pm » |
These statements work as well as ever inside switch statements. If your code results don't match your expectations, then the problem must lie in either the code or the expectations.  I suggest adding some Serial.print() calls to locate problems. I would start with outputting the value of lcd_key to verify that it's what you think it should be...
|
|
|
|
|
Logged
|
There's always a better way!
|
|
|
|
SE USA
Offline
Faraday Member
Karma: 33
Posts: 3626
@ssh0le
|
 |
« Reply #3 on: April 23, 2012, 11:44:38 pm » |
post your entire code, I see nothing outstanding in the examples provided at first glance (attach it as a text file if need be)
|
|
|
|
|
Logged
|
http://arduino.cc/forum/index.php?action=unread;boards=2,3,4,5,67,6,7,8,9,10,11,66,12,13,15,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,86,87,89,1;ALL
|
|
|
|
Global Moderator
Boston area, metrowest
Offline
Brattain Member
Karma: 249
Posts: 16572
Available for Design & Build services
|
 |
« Reply #4 on: April 23, 2012, 11:54:31 pm » |
What is the value of lcd_key after it is called? lcd_key = read_LCD_buttons();
Does it equal btnHITCH, btnLEVEL, etc, or does lcd_key = 1,2,3 etc?
Some print statements as Morris suggested will help:
lcd_key = read_LCD_buttons(); // read the buttons Serial.print (lcd_key); // what'd you get back?
|
|
|
|
« Last Edit: April 23, 2012, 11:58:05 pm by CrossRoads »
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #5 on: April 24, 2012, 02:18:42 am » |
I thought a switch case was just a neater way of having a bunch of if statements, but I can't find an example of one with any other control statements inside it. Is this not possible?
Absolutely it is possible. Post code that demonstrates the problem. Not a snippet. Stripping your example back to compile, like this: void memSet() { int lcd_key = 1;
switch (lcd_key) // depending on which button was pushed, we perform an action { case 1:
{
}
break;
case 2: {
} break;
case 3: {
} break;
}
}
void setup () {} void loop () {} I get no errors. I can not get an if statement, while loop, or for loop to work inside of a switch case statement. Your example did not have a while, if or for in it, so I don't know what it was supposed to prove. Perhaps also post the error message?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #6 on: April 24, 2012, 02:20:41 am » |
Do I need to use a bunch of if statements instead, or put switch cases inside fewer ifs and whiles?
Or are you saying it compiled but didn't actually work? Well it would be clearer to say so, and demonstrate conclusively in what way it didn't work.
|
|
|
|
|
Logged
|
|
|
|
|
alabama
Offline
Full Member
Karma: 1
Posts: 168
|
 |
« Reply #7 on: April 24, 2012, 06:44:01 am » |
OK, removed some comments, short enough now will follow with more details /*
ADXL3xx Reads an MMs7361 accelerometer and communicates the acceleration to the computer. Using a MMS7361 analog breakout instead http://www.arduino.cc/en/Tutorial/ADXL3xx The circuit: analog 0: input for the shield buttons analog 1: power pin to wake accelerometer analog 2: x-axis analog 3: y-axis analog 4: z-axis digital 2: to transistor controlling 12v auto relay digital 3: to transistor controlling 12v auto relay digital 11: leg limit switch digital 10: pwm output for lcd led */ #include <LiquidCrystal.h> #include <EEPROM.h>
// select the pins used on the LCD panel (RS,E,D4,D5,D6,D7) (D10 is backlight control) LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // pinout for DFRobot lcd
// these constants describe the pins. They won't change:
const int upoutpin = 2; // up relay power const int downoutpin = 3; // down relay power (D4-9: LCD) const int numReadings = 10; //number of pin readings to average const int dimLed = 10; // Led brightness control const int legsw = 11; // const int resetEeprom = 12; const int slpin = 15; // pin to wake or power-save accelerometer
// set up averaging parameters int readings[numReadings]; // the readings from the analog input int index = 0; // the index of the current reading int total = 0; // the running total int average = 0; // the average int inputPin = A2; // input for x axis int lcd_key = 0; //setup switch for buttons int adc_key_in = 0;
#define btnHITCH 0 #define btnUP 1 #define btnDOWN 2 #define btnLEVEL 3 #define btnTRAVEL 4 #define btnNONE 6
int x,y,z; float vx; int levelVal = 0; // store level position int hitchVLow; // average value when hitched int hitchVHigh; // average value when raised int hitchDifference; // store this hitchVHigh - hitchVLow int unHooked; //unhitched hieght
// read the buttons int read_LCD_buttons() { adc_key_in = analogRead(0); // read the value from the sensor // my buttons when read are centered at these valies: 0, 110, 300, 475, 600 using 3.3 aref with 1K resistor // we add approx 50 to those values and check to see if we are close if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result if (adc_key_in < 50) return btnHITCH; if (adc_key_in < 180) return btnUP; if (adc_key_in < 380) return btnDOWN; if (adc_key_in < 545) return btnLEVEL; if (adc_key_in < 800) return btnTRAVEL; // Check values when using AREF pin at 3.3v
return btnNONE; // when all others fail, return this... }
void setup() { // initialize the serial communications: lcd.begin(16, 2); // start the library lcd.setCursor(0,0); // analogReference(EXTERNAL); // set reference to 3.3v - use 3.3v power out pinMode(slpin, OUTPUT); // ready pin wake up accelerometer pinMode(upoutpin, OUTPUT); // ready up relay power pin pinMode(downoutpin, OUTPUT); // ready down relay power pin pinMode (legsw, INPUT); // ready saftey sw pinMode (dimLed, OUTPUT); // ready led brite control pinMode (resetEeprom, INPUT); // ready pin 12 for (int thisReading = 0; thisReading < numReadings; thisReading++) readings[thisReading] = 0;
digitalWrite(resetEeprom, HIGH); // set pullup resistorit digitalWrite(slpin, HIGH); // wake accelerometer digitalWrite(legsw, HIGH); // set pullup resistor analogWrite (dimLed, 150); // dim the led to save current
levelVal = EEPROM.read(1); //Get stored level value hitchDifference = EEPROM.read(12); //Get stored hitch offset }
void memSet() {
lcd_key = read_LCD_buttons(); // read the buttons
switch (lcd_key) // depending on which button was pushed, we perform an action { case btnHITCH:
{ hitchVHigh = average; //Get the upper height to set hitchDifference }
break;
case btnLEVEL: { EEPROM.write((average / 4),1); // save level value to eeprom } break;
case btnTRAVEL: { hitchVLow = average; //get lower hitched value hitchDifference = hitchVHigh - hitchVLow; //calculate hitch offset EEPROM.write(hitchDifference,12); //write offset to eeprom
} break; } } void loop() {
if (resetEeprom == LOW) { memSet(); } else {
// subtract the last reading: total = total - readings[index]; // read from the sensor: readings[index] = analogRead(inputPin); // add the reading to the total: total= total + readings[index]; // advance to the next position in the array: index = index + 1;
// if we're at the end of the array... if (index >= numReadings) // ...wrap around to the beginning: index = 0;
// calculate the average: average = total / numReadings;
// Convert ADC values to voltages // The formula for voltage conversion is v = (ADCREAD*VREF/1023)-ZGV, where ZGV is "Zero-G voltage" (voltage at 0G) // ZGV is found in the spec sheet and happens to be 1.62 or 1/2 VCC in our case. Warning: you need to make the variable signed! // The formula for G conversion is g = v/SENSITIVITY. The sensitvity is also found in the spec sheet and happens to be 800 mV/g here
// Remember to make your units consistent! (g = v[V]*1000 / SEN [mV] ) vx = (average/5.68)-levelVal; // gx = vx*10/8; // vy = (y*3.3/1023)-1.62; // gy = vy*10/8; // vz = (z*3.3/1023)-1.62; // gz = vz*10/8;
lcd.setCursor(0,1); lcd.print("X = "); lcd.print(vx);
lcd_key = read_LCD_buttons(); // read the buttons
switch (lcd_key) // depending on which button was pushed, we perform an action { case btnHITCH:
{ if (average < unHooked) { lcd.setCursor(0,0); lcd.print(" HITCH "); digitalWrite(upoutpin, HIGH); } }
break;
case btnUP: {
lcd.setCursor(0,0); lcd.print(" MANUAL RAISE "); digitalWrite(upoutpin, HIGH); //raise front of trailer manually
} break;
case btnDOWN: { if (digitalRead(legsw == HIGH)) { lcd.setCursor(0,0); lcd.print("MANUAL LOWER "); digitalWrite(downoutpin, HIGH); } } break;
case btnLEVEL: // function here to save level value and/or level trailer {
if (resetEeprom == LOW) // check for reset sw { EEPROM.write (average,1); //store the level value in eeprom } else {
if (digitalRead(legsw == HIGH && average != (levelVal *4 ))) { if(average > (levelVal *4)) { digitalWrite (downoutpin, HIGH ); lcd.setCursor(0,0); lcd.print(" LEVELING "); } else { digitalWrite(upoutpin, HIGH); lcd.setCursor(0,0); lcd.print(" LEVELING "); } } } break; }
case btnTRAVEL: { if (digitalRead(legsw == HIGH)) // limit sw to turn off { digitalWrite(downoutpin, HIGH); lcd.setCursor(0,0); lcd.print("RAISING LEGS "); } break;
} case btnNONE: {
lcd.setCursor(0,0); lcd.print(" NONE "); digitalWrite(upoutpin, LOW); digitalWrite(downoutpin, LOW); } break; }
// delay before next reading: //delay(100); }
}
|
|
|
|
|
Logged
|
Einstein once said you don't really understand anything until you can explain it to your Grandmother
|
|
|
|
alabama
Offline
Full Member
Karma: 1
Posts: 168
|
 |
« Reply #8 on: April 24, 2012, 06:46:19 am » |
Thanks for the replies, Yes it does compile. The switch case that in in the main loop function will move the linear actuator (I have actually built a small mock-up of the mechanical functions including limit switches, accelerometer, relays and actuators), but ignores the limit switches or any control statements put in to read the accelerometer . The accelerometer puts out a ten reading average to the lcd fine.
The problem with the external memset() funtion is it doesn't write to the eeprom like it is supposed to.
I know it will be simple when you tell me, that's why I've waited so long, trying to find my mistake myself. Is there a way to put this code into a regular C IDE with a proper debugger? Stepping in while it executes sure would be nice. Thanks again
|
|
|
|
|
Logged
|
Einstein once said you don't really understand anything until you can explain it to your Grandmother
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 138
Posts: 19067
I don't think you connected the grounds, Dave.
|
 |
« Reply #9 on: April 24, 2012, 06:48:17 am » |
if (digitalRead(legsw == HIGH)) BZZZZT! if (digitalRead(legsw == HIGH && average != (levelVal *4 ))) BZZZZT!
|
|
|
|
« Last Edit: April 24, 2012, 06:49:54 am by AWOL »
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #10 on: April 24, 2012, 06:50:09 am » |
Well spotted AWOL. I was concentrating on why the forum hung, my name disappeared, and I was being insulted by idiots. But you stayed on focus. 
|
|
|
|
|
Logged
|
|
|
|
|
alabama
Offline
Full Member
Karma: 1
Posts: 168
|
 |
« Reply #11 on: April 24, 2012, 06:52:29 am » |
Thanks for the help, obviously the syntax is wrong, where can I find intructions/examples to fix it?
|
|
|
|
|
Logged
|
Einstein once said you don't really understand anything until you can explain it to your Grandmother
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 219
Posts: 13896
Lua rocks!
|
 |
« Reply #12 on: April 24, 2012, 06:53:58 am » |
As an example: if (digitalRead(legsw == HIGH))
should be: if (digitalRead(legsw) == HIGH)
Subtle but important.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 138
Posts: 19067
I don't think you connected the grounds, Dave.
|
 |
« Reply #13 on: April 24, 2012, 06:54:31 am » |
No, the syntax is correct, otherwise the compiler would have complained. It's the semantics that are wrong.
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
alabama
Offline
Full Member
Karma: 1
Posts: 168
|
 |
« Reply #14 on: April 24, 2012, 07:04:31 am » |
Thanks again, I see what is wrong with the second example you gave too. Sooooo embarasing, kind of like when this old southern boy goes in a nice restaurant and tries to pronounce the menu.
|
|
|
|
|
Logged
|
Einstein once said you don't really understand anything until you can explain it to your Grandmother
|
|
|
|
|