Go Down

Topic: Better Idea or easier way to get IP address (Read 716 times) previous topic - next topic

zarobhr

Dec 08, 2012, 01:14 am Last Edit: Dec 08, 2012, 01:50 am by zarobhr Reason: 1
IDE 1.02, UNO R3, also have LCD and a 12 key keypad0-9 and 'E' and "C'
I am writing a routine to allow a user to enter an IP address on the UNO if there is not one already entered. I have only included the code for this section

just curious if anyone sees a way to make more compact , not written in yet is the capturing of the ip and storeing it to eeprom. i would like suggestions on the most feasable way to do and also a suggestion on a way to validate whether it is a valid ip address. I have thought about validateing as it is entered for example
ABC.ABC.ABC.ABC , when A is intered only allow 0 1 or 2 to be entered and if user press three force it back to a 2. then when B is entered , allow 0-9 if A is 0 or 1 but only allow 0-5 if A = 2.
the other way is to allow anything to be typed and then when 'E' on keypad is pressed do sometype of check. what are your thoughts.
here is code so far
Code: [Select]
void getipaddress()
{
  boolean goodIP = false;
  byte IPpos = 1 ;
  lcd.setCursor(7,0);
  lcd.print("Enter IP Address");
  lcd.setCursor(1,1);
  lcd.print("000.000.000.000");
  lcd.setCursor(1,1);
  lcd.blink();
  do
  {
    char key = keypad.getKey();

    if (key != NO_KEY){
      if (key == 'C')//backup
      {
        if (IPpos == 5 || IPpos == 9 || IPpos == 13)//skip over decimal
        {

          IPpos -= 2;
          lcd.setCursor(IPpos, 1);

        }
        else if (IPpos == 1) //dont pass to left of first digit of ip
        {
        }
        else
        {
          IPpos -= 1;
          lcd.setCursor(IPpos, 1);
        }
      }
      else if(key == 'E')
      {
        //code to validate and save to eeprom
      }
      else
      {
        if (IPpos == 3 || IPpos == 7 || IPpos == 11)//skip over decimal
        {
          lcd.setCursor(IPpos, 1);
          lcd.print(key);
          lcd.setCursor(IPpos+2, 1);
          IPpos += 2;
        }
        else if (IPpos == 15) //dont move past last digit of ip
        {
          lcd.setCursor(IPpos, 1);
          lcd.print(key);
          lcd.setCursor(IPpos , 1);
        }
        else
        {
          lcd.setCursor(IPpos, 1);
          lcd.print(key);
          IPpos += 1;
        }

      }
    }
  }
  while (goodIP == false);



  //delay(100000000);


}

PaulS

Code: [Select]
  }
   
  }
  }
  } while (goodIP == false);

Is your tab key broken? If so, use the Tools + Auto Format menu item to properly indent your code. That mess is too hard to follow.

zarobhr


Code: [Select]
  }
   
  }
  }
  } while (goodIP == false);

Is your tab key broken? If so, use the Tools + Auto Format menu item to properly indent your code. That mess is too hard to follow.


Fixed, didnt know that existed but CTRL + T is my new best fried

PaulS

You aren't doing anything with key except printing it. When it comes time to save the IP address being displayed on the LCD, how are you going to get that data?

Consistent placement of the { is the next hurdle. The code is much easier to read now.

zarobhr


You aren't doing anything with key except printing it. When it comes time to save the IP address being displayed on the LCD, how are you going to get that data?

Consistent placement of the { is the next hurdle. The code is much easier to read now.


that was a suggestion i wanted what would be the most feasable way to capture the IP and verify

PaulS

You need a char array. Every time you adjust the printing position on the LCD and print a character, store the character in the corresponding position of the array. Remember that array indexes, like LCD column positions, start at 0.

zarobhr


You need a char array. Every time you adjust the printing position on the LCD and print a character, store the character in the corresponding position of the array. Remember that array indexes, like LCD column positions, start at 0.


so i created the array and i am filling it as the keys are pressed ( in the code if 'E' is pressed it moves the cursor to the right unless it is in last position then it will just print the array on line one of lcd for testing.

I also am checking for valid ip as it is entered.

what i would really like to do is take each part of the ip address that is in array for example ip address 123.145.167.189 is 15 chars in array, when i store to eeprom i want to write as 4 bytes so how do i go about converting portions of the array to a byte

Code: [Select]
void getipaddress()
{
  char IPaddr[16]= {
    '0','0','0','.','0','0','0','.','0','0','0','.','0','0','0'    };

  boolean goodIP = false;
  byte IPpos = 1 ;
  lcd.setCursor(7,0);
  lcd.print("Enter IP Address");
  lcd.setCursor(1,1);
  lcd.print("000.000.000.000");
  lcd.setCursor(1,1);
  lcd.blink();
  do
  {
    char key = keypad.getKey();

    if (key != NO_KEY){
      if (key == 'C')//backup
      {
        if (IPpos == 5 || IPpos == 9 || IPpos == 13)//skip over decimal
        {
          IPpos -= 2;
          lcd.setCursor(IPpos, 1);
        }
        else if (IPpos == 1) //dont pass to left of first digit of ip
        {
        }
        else
        {
          IPpos -= 1;
          lcd.setCursor(IPpos, 1);
        }
      }
      else if(key == 'E')
      {
        //code to validate and save to eeprom
        if (IPpos == 15)
        {
          lcd.setCursor(4, 0);

          lcd.print(IPaddr);
        }
        else if (IPpos == 3 || IPpos == 7 || IPpos == 11)
        {
          lcd.setCursor(IPpos+2, 1);
          IPpos += 2;
        }
        else
        {
          lcd.setCursor(IPpos+1, 1);

          IPpos += 1;
        }
      }
      else
      {
        if (IPpos == 1 || IPpos == 5 || IPpos == 9 || IPpos == 13)
        {
          if (key > '2')
          {
            key = '2';
          }
          lcd.setCursor(IPpos, 1);
          IPaddr[IPpos - 1] = key;
          lcd.print(key);
          IPpos += 1;
        }
        else if (IPpos == 2 || IPpos == 6 || IPpos == 10 || IPpos == 14)
        {
          if (IPaddr[IPpos - 2] == '2' && key > '5')
          {
            key = '5';
          }
          lcd.setCursor(IPpos, 1);
          IPaddr[IPpos - 1] = key;
          lcd.print(key);
          IPpos += 1;
        }
        else if (IPpos == 3 || IPpos == 7 || IPpos == 11 || IPpos == 15)//skip over decimal
        {
          if (IPaddr[IPpos - 3] == '2' && IPaddr[IPpos - 2] == '5' && key > '5')
          {
            key = '5';
          }
          else if (IPaddr[IPpos - 3] == '0' && IPaddr[IPpos - 2] == '0' && key == '0' && (IPpos == 3 || IPpos == 15))
          {
            key = '1';
          }
          lcd.setCursor(IPpos, 1);
          IPaddr[IPpos - 1] = key;
          lcd.print(key);
          if (IPpos == 15)
          {
            lcd.setCursor(IPpos , 1);
          }
          else
          {
            lcd.setCursor(IPpos+2, 1);
            IPpos += 2;
          }
        }

        else
        {
          //lcd.setCursor(IPpos, 1);
          //lcd.print(key);
          //IPpos += 1;
        }
      }
    }
  }
  while (goodIP == false);



  //delay(100000000);


}

PaulS

Code: [Select]
  char IPaddr[16]= {
    '0','0','0','.','0','0','0','.','0','0','0','.','0','0','0'    };

would involve a lot less typing as
Code: [Select]
   char IPaddr[16] = "";

The second one results in a NULL terminated array of chars. There is no telling what is in elements 1, 2, 3, etc., but it doesn't matter because there is a NULL in 0.

Code: [Select]
          IPaddr[IPpos - 1] = key;
needs to be
Code: [Select]
          IPaddr[IPpos - 1] = key;
          IPaddr[IPpos] = '\0';

to keep the string NULL terminated.

When the 'E' key is pressed, you need to use the strtok() and atoi() functions to get the tokens (the parts between the dots) and convert them to numbers.


PeterH

There are already types defined to hold IP addresses in the common ethernet libraries. Have you checked whether there are also library functions to parse a dotted decimal string into an IPv4 address? I would be surprised if there wasn't.

If you can't find anexisting implementation and want to roll your own, the way I'd tackle this problem is to split the input string into four sequences of decimal digits, convert each sequence of digits to a number and verify the number is in the range 0 .. 255. I'd return the result using the existing IP address type, although I suppose you could use a 32-bit int instead.
I only provide help via the forum - please do not contact me for private consultancy.

zarobhr


Code: [Select]
  char IPaddr[16]= {
    '0','0','0','.','0','0','0','.','0','0','0','.','0','0','0'    };

would involve a lot less typing as
Code: [Select]
   char IPaddr[16] = "";

The second one results in a NULL terminated array of chars. There is no telling what is in elements 1, 2, 3, etc., but it doesn't matter because there is a NULL in 0.

the reason i did this way is so that if a user presses E to the end without actually pressing numbers there will be a default already there

Code: [Select]
          IPaddr[IPpos - 1] = key;
needs to be
Code: [Select]
          IPaddr[IPpos - 1] = key;
          IPaddr[IPpos] = '\0';

to keep the string NULL terminated.
the last 16th position has the null, if i try like this and you backspace with c and change the value the null moves and i need to keep null at the end

When the 'E' key is pressed, you need to use the strtok() and atoi() functions to get the tokens (the parts between the dots) and convert them to numbers.

i will try these functions in a few minutes




Go Up