Show Posts
Pages: [1] 2
1  Using Arduino / Programming Questions / Re: Nested switch...case on: January 14, 2013, 01:58:37 am
I tried adding a function and I couldn't give it user input properly, I could only back out of the menu... Here is my entire code at the moment:

Code:
#include <Keypad.h>

#include <glcd.h>
#include <glcd_Buildinfo.h>
#include <glcd_Config.h>

#include "fonts/allFonts.h"

int ledPin = 13;

boolean menuActive = false; //

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {
    '1','2','3'  }
  ,
  {
    '4','5','6'  }
  ,
  {
    '7','8','9'  }
  ,
  {
    '*','0','#'  }
};
byte rowPins[ROWS] = {
  40, 41, 42, 43}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  44, 45, 46}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
  pinMode(ledPin, OUTPUT);
  GLCD.Init();
  GLCD.SelectFont(System5x7);
  GLCD.println("VOSHA UCP");
  GLCD.println("Press * for menu");
  GLCD.println("1. Lamp toggle");
  GLCD.println("2. Alarm silence");
  GLCD.println("3. Alarm sound");
  GLCD.println("4. LED value set");
}

void loop() {
  char key = keypad.getKey();
  switch (key) {
  case '*':
    menuActive = true;
    GLCD.ClearArea();
    GLCD.println("1. LED On");
    GLCD.println("2. LED Off");
    GLCD.println("3. LED Blink");
    GLCD.println("4. Master Config");
    GLCD.println("5. MenuItem5");
    GLCD.println("6. MenuItem6");
    GLCD.println("7. MenuItem7");
    GLCD.println("# To exit menu");
    break;

  case '#':
    menuActive = false;
    HomeScreen();
    break;

  case '1':
    if (menuActive == true) {
      digitalWrite(ledPin, HIGH);
      ActionCompleted();
    }
    break;

  case '2':
    if (menuActive == true) {
      digitalWrite(ledPin, LOW);
      ActionCompleted();
    }
    break;

  case '3':
    if (menuActive == true) {
      ActionCompleted();
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
    }
    break;

  case '4':
    if (menuActive == true) {
      MasterConfig();
      break;

    default:
      break;
    }
  }
}

void HomeScreen() { //Routine to display home screen and provide updates
  GLCD.ClearArea();
  GLCD.println("VOSHA UCP");
  GLCD.println("Press * for menu");
  GLCD.println("1. Lamp toggle");
  GLCD.println("2. Alarm silence");
  GLCD.println("3. Alarm sound");
  GLCD.println("4. LED value set");
}

void ActionCompleted() {
  GLCD.ClearArea();
  GLCD.CursorTo(0,0);
  GLCD.print("Action completed!");
  delay(500);
  menuActive = false;
  HomeScreen();
}

void MasterConfig() {
  menuActive = false;
  GLCD.ClearArea();
  GLCD.println("Master Configuration");
  GLCD.println("# To exit menu");
  GLCD.println("1. Device ID");
  char key2 = keypad.getKey();
  switch (key2) {
  case '1':
    GLCD.ClearArea();
    GLCD.println("Device ID menu");
    break;
  default:
    break;
  }
}

MasterConfig is where I have moved that menu to try out Hazards suggestion and I can't give it input...

uber
2  Using Arduino / Programming Questions / Re: Nested switch...case on: January 13, 2013, 06:11:38 pm
I'll have to try that tomorrow, I've switched my laptop off for the night now

uber
3  Using Arduino / Programming Questions / Re: Nested switch...case on: January 13, 2013, 05:54:06 pm
Yes, the menu system is supposed to be blocking as the actions are performed in the root menu itself. I am trying to get the user input to this one sub menu but it keeps triggering the second function (To turn on the LED) in the menu above the main configuration menu which isn't what I want and the only way I could see this possible is to put the menu in a routine and then call it and just pass it user input from the loop :/

uber
4  Using Arduino / Programming Questions / Re: Nested switch...case on: January 13, 2013, 05:49:48 pm
Just tried this now as you suggested:
Code:
    case '4':
      if(menuActive == true){
        GLCD.ClearArea();
        GLCD.println("Master Configuration");
        GLCD.println("# To exit menu");
        GLCD.println("1. Device ID");
        char key2 = keypad.getKey(); //Used for this sub menu only
          switch (key2) {
            case '1':
            GLCD.ClearArea();
            GLCD.println("Device ID menu");
            break;
      }

And it still toggles the LED, this is infuriating...

uber
5  Using Arduino / Programming Questions / Re: Nested switch...case on: January 13, 2013, 05:36:40 pm
Just tried this. Again, to no avail...
Code:
   
case '4':
      if (menuActive == true) {
        menuActive = false;
        GLCD.ClearArea();
        GLCD.println("Master Configuration");
        GLCD.println("# To exit menu");
        GLCD.println("1. Device ID");
          switch (key) {
            case '1':
            //if(key == '1')
            GLCD.ClearArea();
            GLCD.println("Device ID menu");
            break;
      }
    break;

I tried disabling access to the menu system but that seems to lock me out entirely and if I remove the menuActive = false line I'm back to the problem of it turning the LED on again...  :S

uber
6  Using Arduino / Programming Questions / Re: Nested switch...case on: January 13, 2013, 05:31:39 pm
I did try that earlier before I posted and it didn't seem to like nested switches, I'll try again now...

uber
7  Using Arduino / Programming Questions / Re: Nested switch...case on: January 13, 2013, 05:28:07 pm
Just tried throwing this in on the end:
Code:
case '4':
      if (menuActive == true) {
        GLCD.ClearArea();
        GLCD.println("Master Configuration");
        GLCD.println("# To exit menu");
        GLCD.println("1. Device ID");
          if(key == '1') { //This toggles the function to enable LED instead of entering menu
            GLCD.ClearArea();
            GLCD.println("Device ID menu");
          }
      }

And it just enabled the other function with the same key that it was assigned to... I'm thinking about toggling the main menu lock once I get into a lower menu...

uber
8  Using Arduino / Programming Questions / Nested switch...case on: January 13, 2013, 05:17:02 pm
I am trying to write a menu system to integrate with my home automation system but I have run across a problem with nested switch...case switches used to perform the menu routines. The menu is driven off one keypad and needs to be multi-level.

This is the menu code so far:
Code:
void loop() {
  char key = keypad.getKey();
  switch (key) {
    case '*':
      menuActive = true; //Allows access to the menu
      GLCD.ClearArea();
      GLCD.println("1. LED On");
      GLCD.println("2. LED Off");
      GLCD.println("3. LED Blink");
      GLCD.println("4. Master config");
      GLCD.println("5. MenuItem5");
      GLCD.println("6. MenuItem6");
      GLCD.println("7. MenuItem7");
      GLCD.println("# To exit menu");
    break;
   
    case '#': //Disables menu access
      menuActive = false;
      HomeScreen(); //Basic home screen presenting user with some basic options
    break;
   
    case '1':
      if (menuActive == true) {
        digitalWrite(ledPin, HIGH); //For testing only
        ActionCompleted();
      }
    break;
   
    case '2':
      if (menuActive == true) {
        digitalWrite(ledPin, LOW);
        ActionCompleted(); //Generic screen to show user action performed sucessfully
      }
    break;
   
    case '3':
      if (menuActive == true) {
        ActionCompleted();
        digitalWrite(ledPin, HIGH);
        delay(100);
        digitalWrite(ledPin, LOW);
        delay(100);
        digitalWrite(ledPin, HIGH);
        delay(100);
        digitalWrite(ledPin, LOW);
      }
    break;
   
    case '4':
      if (menuActive == true) {
        GLCD.ClearArea();
        GLCD.println("Master Configuration");
        GLCD.println("# To exit menu");
        GLCD.println("1. Device ID");
          case '1': //Error is given on this line because the number 1 is used twice...
            GLCD.ClearArea();
            GLCD.println("Device ID menu");
          break;
      }
    break;
  }
}

The error says:
VOSHA_UCP.ino: In function 'void loop()':
VOSHA_UCP:116: error: duplicate case value
VOSHA_UCP:66: error: previously used here

But I need that to work to provide me with a multi level menu. Is there any workarounds to this problem?

uber
9  Using Arduino / General Electronics / RFID Reader library on: August 26, 2012, 04:34:17 am
Does anyone know of a library for a MF522-AN RFID reader? I recently bought one off ebay and looking at the example code confused me. A lot.
This is the reader: http://www.ebay.co.uk/itm/RFID-13-56Mhz-Module-Tags-SPI-Interface-Read-Write-for-Arduino-UNO-R3-Mega-MCU-/170859728113?pt=UK_Computing_Other_Computing_Networking&hash=item27c8088cf1#ht_2473wt_1271 and they can be found all over ebay...

If any of you guys think it would be easier to just buy a Parallax or a Sparkfun reader, leave me a comment...

callum
10  Using Arduino / Programming Questions / Re: Sending serial data from within a loop on: August 14, 2012, 12:44:14 pm
Wow! Thanks a lot for all your help! The routine is working fine and I just need to sort out some bugs in the alarm setting code so I just give one push of a button and it arms...

A happy Callum!
11  Using Arduino / Programming Questions / Re: Sending serial data from within a loop on: August 14, 2012, 12:32:05 pm
I'll try initializing it the way you said and let you know...

Callum
12  Using Arduino / Programming Questions / Re: Sending serial data from within a loop on: August 14, 2012, 10:26:12 am
I'll edit the code now and upload it to my arduino when I get back home and let you know...
Thanks for all the help smiley

Callum

Edit: Just uploaded the sketch and its still running in a loop but I'm going to add another few variables and some logic that locks the routine from being run by that bit of code again until another call comes along and unlocks it...
13  Using Arduino / Programming Questions / Re: Sending serial data from within a loop on: August 14, 2012, 10:14:00 am
Ok, be warned: its 264 lines long...

Code:
  /*----ARDUINO HOME AUTOMATION----
  Yes, you are free to modify and redistribute the code, just keep this disclaimer in!
  Disclaimer:
     I don't and won't be liable for any injury or losses associated with the use of this code!!
     It is probably riddled with bugs but you can solve them if you find them, also, if you
     notice any major problems that you have updated, please email a copy of the code to me
     uberdum05@gmail.com
     
     Code created: late 2011-early 2012
     by: Callum Snowden
     Feel free to redistribute but keep this credit in please :)
     
     If you have any questions, you can find me at:
     uberdum05@gmail.com
     -or-
     pluselectronics.wordpress.com
     
     Yes, I am only 14 and it took a lot of work to make this so can you just keep this credit please?
  */
 
  #include <LiquidCrystal.h>
  #include <Password.h>
  #include <Keypad.h>
 
  int strobe = 53; //Connected to relay and then to 12V strobe light
  int alarmIn = 52; //Emergency alarm input - switches everything off and activates alarm outputs
  int alarmInVal = LOW; //Set true if alarm input is triggered
  int alarmSetButton = 51; //Enable/disable the alarm subsystem (just a push on-off SPST button)
  int alarmSetVal; //Used for alarm setting/unsetting
  int doorSwitch = 50; //Pin for the door sensor (reed switch w/magnet taped to door)
  int alarmSiren = 40; //Output for the alarm siren
 
  int lightThreshold = 275; //Value when lamp needs to be turned on
  int lightLevel = 0; //Variable to hold the light level
  int lightSensor = 0; //Pin on which the LDR is on
 
  int interval = 1000; //Update interval for the LCD (most likely not needed once on beta 1.1)
  int previousMillis; //The last interval when the Millis() function was taken
  boolean lcdStat = true; //Hmmm, I can't remember what this was used for...
  int val = 0; //This may not be needed, just keep it though
  boolean pw_set; //Used to allow main code to run if password is ok
  Password password = Password("1337"); //Should be quite obvious!
  LiquidCrystal lcd(22,23,24,25,26,27); //Change to match your LCD pins
 
  unsigned long alarmTime = 0; //Time (millis()) when alarm was triggered for timout period
  unsigned long currentMillis = 0; //Keeps track of current time
 
  int heartbeatLED = 41; //LED Used for signalling that the system is still ok and hasn't hung
 
  //USED FOR SERIAL SEND ROUTINE!
  boolean sendSerialMessage = false; //Used for the sendSerial subroutine to check when conditions are ripe for sending
  char serialMsg; //Used to hold the message for sending via serial
 
 
  int chnlA = 13; //Channel A output
  int chnlAstat = LOW;
 
  /* * LCD RS pin to digital pin 22
   * LCD Enable pin to digital pin 23
   * LCD D4 pin to digital pin 24
   * LCD D5 pin to digital pin 25
   * LCD D6 pin to digital pin 26
   * LCD D7 pin to digital pin 27
   */
 
  const byte ROWS = 4; // Four rows
  const byte COLS = 4; //  columns
  // Define the Keymap
  char keys[ROWS][COLS] = {
    {'1','2','3', 'A'},
    {'4','5','6', 'B'},
    {'7','8','9', 'C'},
    {'*','0','#', 'D'}
  };
  byte rowPins[ROWS] = {28,29,30,31};
  byte colPins[COLS] = {32,33,34,35};
 
  Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
  KeypadEvent eKey;
 
  void setup(){
    Serial.begin(9600);
    Serial.println("#---------------------#");
    Serial.println("VOSHA HOME AUTOMATION");
    Serial.println("VERSION: 2.2B Parrot");
    Serial.println("#---------------------#");
    keypad.addEventListener(keypadEvent);
    lcd.begin(16, 4);
    lcd.print("VOSHA Home Auto");
    lcd.setCursor(0, 1);
    lcd.print("Version: 2.2");
    delay(500);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Starting.");
    delay(250);
    lcd.clear();
    lcd.print("Starting..");
    delay(250);
    lcd.clear();
    lcd.print("Starting...");
    delay(250);
    lcd.clear();
    lcd.print("Starting.");
    delay(250);
    lcd.clear();
    lcd.print("Starting..");
    delay(250);
    lcd.clear();
    lcd.print("Starting...");
    delay(250);
    lcd.clear();
    lcd.print("Starting.");
    delay(250);
    lcd.clear();
    lcd.print("Starting..");
    delay(250);
    lcd.clear();
    lcd.print("Starting...");
    delay(250);
    lcd.clear();
    pinMode(chnlA, OUTPUT); pinMode(strobe, OUTPUT); pinMode(alarmIn, INPUT); pinMode(alarmSetButton, INPUT); pinMode(doorSwitch, INPUT); pinMode(alarmSiren, OUTPUT); pinMode(heartbeatLED, OUTPUT);
    digitalWrite(alarmIn, HIGH); digitalWrite(alarmSetButton, HIGH); digitalWrite(doorSwitch, HIGH);
    lcd.print("Password:");
  }
 
 
  //SERIAL SEND ROUTINE FOR SENDING SERIAL DATA!
  void serialSend(){
    if(sendSerialMessage == true){
      Serial.println(serialMsg);
      sendSerialMessage = false;
    }
  }
 
 
  void loop(){
    currentMillis = millis();
    lcd.setCursor(0, 2);
    keypad.getKey();
   
    if(pw_set == true){ //Menu subsystem
      lcd.setCursor(0, 0);
      lcd.print("VOSHA Home Auto");
      lcd.setCursor(0, 1);
      lcd.print(chnlAstat);//Status of output channel A
  switch (keypad.getKey()){
    case '#': //Lock routine
                    password.reset();
                    Serial.println("Reset!");
                    lcd.clear();
                    lcd.print("Password:");
                    val = 0;
                    pw_set = false; //Locks the menu subsystem
                  break;
            case '*':  //Once you are logged in, this will reset all the alarms unless they are still triggered
                    if (alarmInVal == HIGH){
                      alarmInVal = LOW;
                      digitalWrite(strobe, alarmInVal);
                    }
                    digitalWrite(alarmSiren, LOW);
                    Serial.println("All alarms reset!");
                  break;
            case 'A':
                              if (chnlAstat == LOW){
                chnlAstat = HIGH;
            }else{
                chnlAstat = LOW;
            }
           digitalWrite(chnlA, chnlAstat);
           Serial.println("Lamp: " + chnlAstat);
                  break;
  }
    } //End of menu subsystem
    homeAutomation();
   
 
  }
 
  void keypadEvent(KeypadEvent eKey){
    if(pw_set == false){
    switch (keypad.getState()){
      case PRESSED:
  Serial.print("Pressed: ");
  Serial.println(eKey);
  switch (eKey){
    case '*':
                  guessPassword(); //Calls password verification routine
                  break;
    case '#': //Clears the current password and displays msg
                  password.reset();
                  Serial.println("Reset!");
                  lcd.clear();
                  lcd.print("Password:");
                  val = 0;
                  break;
    default: //What normally happens. ie append the password
  password.append(eKey);
                  lcd.setCursor(val, 1);
                  lcd.print("*");
                  val = val + 1;
       }
    }
    lcd.setCursor(0,1);
    }
  }
 
  void guessPassword(){  //Password verification routine
       Serial.print("Verifying password... ");
       if (password.evaluate()){
          Serial.println("OK");
          Serial.println("System logged in");
          lcd.clear();
          lcd.print("OK");
          password.reset();
          pw_set = true;   
       }else{
  Serial.println("ERROR!");
          lcd.print("ERROR!!         ");
          delay(750);
          lcd.clear();
          password.reset();
          lcd.print("Password:");
          val = 0;
       }
 
  }
 
  void homeAutomation(){
    if (digitalRead(alarmIn) == LOW){
      alarmInVal = HIGH;
      digitalWrite(chnlA, LOW);
      digitalWrite(strobe, alarmInVal);
      Serial.println("Emergency alarm activated!");
    }
   
    if(digitalRead(alarmSetButton) == LOW && digitalRead(doorSwitch) == LOW)
    {
      digitalWrite(alarmSiren, HIGH);
      alarmTime = millis();
     
      //DEALS WITH SETTING UP FUNCTION AND CALLING FUNCTION!!
      serialMsg = 'Alarm!'; //Must be called before activating function!
      sendSerialMessage = true; //Tells function OK to send
      serialSend; //Finally runs function itself
     
    }
   
    if(currentMillis - alarmTime > 120000)//Compares time when alarm sounds to current time (120000 is 2 minutes)
    {
      digitalWrite(alarmSiren, LOW);
    }
   
      lightLevel = analogRead(lightSensor);
    if(lightLevel == lightThreshold){
      chnlAstat = HIGH;
      digitalWrite(chnlA, HIGH);
    }
    heartbeat();
  }
     
  void heartbeat(){
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

I am trying to send over serial a full sentence ie 'Burglar Alarm!' but when I just used Serial.println(); to send that, it worked fine but it just overloaded the serial port which feeds straight into twitter. The function is only designed to run once but it won't handle that string and its starting to cause problems associated with raising the alarm...
14  Using Arduino / Programming Questions / Re: Stuck in a loop on: August 14, 2012, 09:40:21 am
Wouldn't setting a boolean flag work to hold the on/off state of the lights? EG Once it receives the on code from the remote, flip the value of the variable and then once the off code is received, flip it back to false and then have your code surrounded in an if loop that doesn't run if the variable is false with the IR receiving code outside the loop?
Just my 10 cents...

Callum
15  Using Arduino / Programming Questions / Re: Sending serial data from within a loop on: August 14, 2012, 09:22:43 am
Edit: After installing a heartbeat LED just to monitor the system which is just updated after each successful loop, it looks like the system hangs when the code that silences the alarm automatically is running. This bit in particular:
Code:

if(currentMillis - alarmTime > 120000)//Compares time when alarm sounds to current time (120000 is 2 minutes)
  {
    digitalWrite(alarmSiren, LOW);
  }
So it looks like I will have to set a variable once the alarm starts and then reset it once the serial send function is finished like Paul said...

Edit Pt.2:
Wrote new code for the serial send routine which checks a boolean flag and I'm now getting this error relating to this line:
Code:
    serialMsg = "Burglar alarm!"; //Must be called before activating function!
The error is:
Invalid conversion from 'const char*' to 'char'

How can I handle sending strings?!
Someone please help before I blow a fuse!

Callum
Pages: [1] 2