Terminal string not getting updated

OK so first I’ll explain what I am exactly doing.
I am using NodeMCU and have set up Blynk terminal at V1 pin. I have written a program to change the wifi ssid and password from the terminal. These settings can be changed by typing “change credentials” in terminal and it will ask me for a confirmation i.e. “Do you want to proceed”, “type YES/EXIT”.
So now when I send “YES” the program does not update the string due to which I am unable to proceed further. After debugging what I found that data stored in string is not getting updated and remains the same i.e. change credentials.
So I tried specified a void function say void update() and added the BLYNK_WRITE(V1) in it so that I will call the function when ever I want to read data sent from terminal. But this was not allowed and gave me error. What changes should I do in the program or is there any better way by which I can achieve this?

Please feel free to ask me if you don’t understand what I meant to say.
Here is the entire code


#define BLYNK_PRINT Serial
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimeLib.h>
BlynkTimer timer;
char auth[] = "xxxxxxxxx";
char ssid[] = "xxxxxx";
char pass[] = "xxxxxxxx";
String values;
WidgetTerminal terminal(V1);

BLYNK_WRITE(V1)
{
  values = param.asString();      
}

void terminals()
{
 if (String("CHANGE CREDENTIALS") == values|| String("change credentials") == values) 
 {  
   terminal.println("WARNING");
   terminal.println("-------------");
   terminal.println("Improper changes of settings will disconnect your device");
   terminal.println("Do you want to continue?");
   terminal.println("YES/ EXIT");
   getAndPut();
   if(String("Yes") == values)
   {
     terminal.println("Your Current Settings are:");
     terminal.print("SSID:");
     terminal.println(ssid);
     terminal.print("Password:");
     terminal.write(pass);
     terminal.println("Type new SSID");
   } 
 } 
 terminal.flush();
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  terminal.println("Blynk v" BLYNK_VERSION ": Device started");
  terminal.println("-------------");
  timer.setInterval(1000L, terminals);
}

void loop()
{
  Blynk.run();
  timer.run();
}

It’s because your credentials are hard coded.

When you type in your new details it will update the char arrays like you wish but by that time the connection has already been made in void setup.

Then when you come to turn off your device and back on it will revert to using the details you hard coded originally.

Have a google for eeprom.(nodemcu etc may have a better way but back in old school Arduino days that’s what was needed) That’s where you need to store your credentials so that upon boot they can be pulled from memory and used for the connection.

Edit: also from the looks of your code your function doesn’t update the credentials either. I’m using my phone at the minute so can’t really write the function for you. You need to take the input of the terminal and set your ssid variable to it.

But all that aside you need to find a different way to store your credentials because it won’t really make a difference and you will have to do this after every reboot using this method.

also check out WifiManager library (not in Blynk) but can be used with it.

1 Like

@JustBertC and @DaleSchultz Thankyou for your reply.
I completely forgot to mention that the program isn’t complete at all. Hence there are no lines that will read and store new typed ssid or password.
Actually this code is just for testing which will be added up into the main project code.
Once ssid or password of router is changed, the only way to update it in the program is by actually typing it in Arduino IDE which other people, one having no programming knowledge may not understand. So by using terminal and replacing the previous ssid and password we can surely do it. Yes even I know that NodeMCU will disconnect from internet once after Password is changed and if I reset the device everything will go back to previous state. I have already planned of using eprom for same but thats no the problem here.
Strings send from terminal are not getting updated. While I am in the first if condition, even if I type and send something from terminal the string won’t get updated.

I’ll explain you the flow what is expected to happen

  1. I send ‘change credentials’ from terminal.
  2. NODEMCU will show me a warning message and ask for confirmation.
  3. Now i send yes from terminal as confirmation.
  4. Next NODEMCU will show me the current ssid and password and then i will type new password.
    But step 4 does not execute even if I type yes that’s because the string won’t get update.
    Please ask me again if you have any doubts or haven’t got my point.

Are you sure?
You’re calling a function called “getAndPut” that doesn’t exist:

The reason why you’re not able to progress beyond entering “CHANGE CREDENTIALS” or “change credentials” is because of the way that you’ve structured the first ‘if’ statement in void terminals().

If you enter anything other than “CHANGE CREDENTIALS” or “change credentials”, the first ‘if’ statement will fail, so when values = "Yes", you don’t get beyond this line:

BTW, I find it odd that you do your string comparison this way around, the 'normal way would be:

if (values=="CHANGE CREDENTIALS" || values=="change credentials")

and I’m not sure that it’s necessary to turn the values string into a string to compare it with the string literals of “CHANGE CREDENTIALS” and “change credentials”.

As has already been pointed-out, even when you get to a point where you capture the new SSID and password, using them isn’t easy. You’d have to write them to non-volatile memory (SIFFS or NVRAM) and re-load them to use them, as your new Wi-Fi credentials. A reboot, or Wi-Fi disconnect/reconnect would be needed to make the new credentials take effect.

Pete.

yes we are probably getting mislead by what you want to do with the data, and not focusing on the problem - perhaps give us just a minimal sketch showing the issue of the terminal.

Yaa even forgot to remove getAndPut(). I repost proper program again.
But as I said just ignore the part of how exactly I am going to replace current ssid and password and storing it permanently. Currently main aim is to read and get new ssid and password typed from terminal which is not getting done .
Did you understand where exactly am I stucked snd what problem I am facing because I know I am not able to explain you guys the exact problem. Please let me know if there is any doubt.

Yaa by the way I dont have proper coding skills.:joy::joy: I was editing the example code which had that string comparison done in odd fasion.

:slightly_smiling_face:

@DaleSchultz
Yes you are right. You guys are getting misleaded and not on the problem.
I’ll add screenshots of what exactly happened on the terminal and proper explanation of each with a proper program.
Thanks!!!

Yes, I believe I did.
I’ve also explained to you why you’re facing this problem - because of the structure of your ‘if’ statement. Did you understand that?

Pete.

1 Like
{
 if (String("CHANGE CREDENTIALS") == values|| String("change credentials") == values) 
 {  
   terminal.println("bla, bla...");
   terminal.println("YES/ EXIT");
   if(String("Yes") == values) // Will NEVER get to this point because the 'values' has changed from CHANGE CREDENTIALS or change credentials
   {

This is not a Blynk issue… just bad coding logic.

1 Like

Yes definitely this is a bad coding logic. After the line terminal.println("YES/ EXIT");
program should wait and check for new string from terminal. But what should I specify after this line that will check if the user has send new string.

{
 if (String("CHANGE CREDENTIALS") == values|| String("change credentials") == values) 
 {  
   terminal.println("bla, bla...");
   terminal.println("YES/ EXIT");
// add a command that will wait for new string send from terminal
   if(String("Yes") == values) 
   {

This should be done, right?

This is what I tried before posting a question on blynk. But this gave me some error and I have no idea whether this is even allowed

void check()
{
BLYNK_WRITE(V1)
{
  values = param.asString();      
}
}

void terminals()
{
check(); // check if user has send any string
 if (String("CHANGE CREDENTIALS") == values|| String("change credentials") == values) 
 {  
   terminal.println("WARNING");
   terminal.println("-------------");
   terminal.println("Improper changes of settings will disconnect your device");
   terminal.println("Do you want to continue?");
   terminal.println("YES/ EXIT");
   check();  // check again if user has send any string
   if(String("Yes") == values)
   {
     terminal.println("Your Current Settings are:");
     terminal.print("SSID:");
     terminal.println(ssid);
     terminal.print("Password:");
     terminal.write(pass);
     terminal.println("Type new SSID");
     \\ After this I have to add more lines that will store and replace current ssid and password. 
   } 
 } 
else
 {
  terminal.print(values);
 }
 terminal.flush();
}

void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  terminal.println("Blynk v" BLYNK_VERSION ": Device started");
  terminal.println("-------------");
  timer.setInterval(1000L, terminals);
}

void loop()
{
  Blynk.run();
  timer.run();
}

    .....

Futher I also should specify something that will clear the stored string as program started to stuck in loop. But how should I do this?
I have also added a screenshot of the terminal.


Here after typing ‘change credential’ only once, program kept on sending the same message again and again.

I would consider using a Switch Case function for all your terminal inputs, along with && flagging to determine if a YES, etc. is meant to be a valid answer or just disregarded as out of place text.

Can you write a program or show me some example. What do you meant by flagging?
Specifying every condition in switch case will become complicated, right? I will have to make cases for each that have to be executed in a proper sequence i.e first confirmation i.e yes/exit then show current ssid and password and, then type new ssid then type new password.
I’ll still try it out and tell you what I get.

We try to teach about Blynk here, not how to program… but here are some tips.

Google or search this forum for Switch Case Since it expects integers or characters, you might have to change up what is typed in from YES or NO to Y for YES N for NO, etc. Experiment :slight_smile:

Also Google for something like flag code in arduino

Define a flag (call it whatever you want)

int flag = 0;

Check a flag setting… if (flag == 0) {// do something}

And if not set then do something and then (if required) change the flag flag = 1; to prevent further doings of something.

The combine the two with Switch case options for all your expected inputs and flagging to determine the logic of running some results when text is entered, or looping back to waiting for input.

This is NOT drop in code, it is untested and I am unsure of the letters will even work??? EDIT - see here for use with single character input - https://www.arduino.cc/en/Tutorial/SwitchCase2

You need to test and tweak it.

switch (inByte) {
  case 'C':  // Change Credentials
    // Set flag to 1
    // print next user options to enter
    break;
  case 'Y':  // Yes
    // if flag == 1 do something then Yes like, then reset flag to 0
    // else go back to waiting for input
    break;
  case 'N':  // No
    // if flag == 1 do something No like, then reset flag to 0
    // else go back to waiting for input
    break;
  default:
    // if nothing else matches, do the default
    // default is optional
    break;
}
1 Like

Here’s some code. Completely untested but based on what @Gunner has mentioned.

(I know it could be condensed a lot but it’s just an example)

You should be able to use it as a base to get you going:


int iState = 0;

BLYNK_WRITE(Vx){

  String tInput = param.asStr();

  switch (iState){

    case 0:
      terminal.println("Main menu");
      terminal.println("Type CC to change WiFi credentials");
      terminal.flush();
      iState = 1;
      break;

    case 1:
      if (tInput == "CC"){
        iState = 2;
      } else if (tInput == "Exit"){
        iState = 0;
      }
      break;

    case 2:
      terminal.println("Current credentials:");
      terminal.print("SSID: ");
      terminal.println(ssid);
      terminal.print("Pass: ");
      terminal.println(pass);
      terminal.println("");
      terminal.println("Change details?");
      terminal.println("Type Y or N");
      terminal.flush();
      iState = 3;
      break;

    case 3:
      if (tInput == "Y"){
        iState = 4;
      } else if (tInput == "N"){
        iState = 0;
      }
      break;

    case 4:
      terminal.println("Enter new SSID");
      terminal.flush();
      iState = 5;
      break;

    case 5:
      ssid = tInput;
      terminal.println("Enter new pass");
      terminal.flush();
      iState = 6;
      break;

    case 6:
      pass = tInput;
      terminal.println("You entered:");
      terminal.print("SSID: ");
      terminal.println(ssid);
      terminal.print("Pass: ");
      terminal.println(pass);
      terminal.println("");
      terminal.println("Save or change details?");
      terminal.println("Type S or C");
      terminal.flush();
      iState = 7;
      break;

    case 7:
      if (tInput == "S"){
        iState = 8;
      } else if (tInput == "C"){
        iState = 4;
      }
      break;

    case 8:
      terminal.println("Credentials saved.");
      terminal.println("");
      terminal.flush();
      iState = 0;
      break;
  }
}

2 Likes

@Gunner and @JustBertC thank you guys!
I have understood the changes to be done in the program. I’ll definitely try it out once I get time and let you know what I get.

1 Like

Hello guys!
Tried the code given by JustBertC along with some modifications and it works perfectly fine. I also added eprom feature so that the new ssid and password could get permanently stored. After updating ssid and password Nodemcu did connect again to Blynk server without any issue.
Thank you guys!!!

2 Likes

now it is your turn to give us the complete sketch helping the guys that need this functionality !

3 Likes

Sure!
I’ll post it as soon as I get time.

2 Likes

Heres the link for code. It has two files one named Terminaltest.ino and EPROM.h.
Code for storing data in EEPROM is written with the help of Template_ESP8266 program.

Link: https://drive.google.com/drive/folders/1-Cr_ZneYjihZMrxxrUPNkOJ3YobOLFS3?usp=sharing

Thank you guys for your help!!! :smiley:

2 Likes