Is it possible to format the input from the serial monitor?

Is it possible to input a string into the serial monitor and then format it? As an illustration of what I mean, if I run the following sketch:

    Serial.println("Enter a code string:");
    while (Serial.available() <= 0) {
      delay(100);
    }
    String code = Serial.readStringUntil('\n');
    Serial.println(code);
    String codeString = "import machine\nimport utime\n\ngpio0 = machine.Pin(0, machine.Pin.OUT)\ngpio45 = machine.Pin(45, machine.Pin.OUT)\nutime.sleep(1)\ngpio45.value(0)\ngpio0.value(1)";
    //Serial.print("Code sent to server");
    Serial.println(codeString);

The result in the serial monitor is:

Enter a code string:

"import machine\nimport utime\n\ngpio0 = machine.Pin(0, machine.Pin.OUT)\ngpio45 = machine.Pin(45, machine.Pin.OUT)\nutime.sleep(1)\ngpio45.value(0)\ngpio0.value(1)"

import machine

import utime

gpio0 = machine.Pin(0, machine.Pin.OUT)

gpio45 = machine.Pin(45, machine.Pin.OUT)

utime.sleep(1)

gpio45.value(0)

gpio0.value(1)

As you can see the inputted string is printed as a string whereas the scripted string is formated according to the "\n"s in the string. How can I do this formatting with the inputted string?

Since you are assured the String end at the \n, always add a second print line to print a CR.

By the way, your program will soon run out of memory as you are creating many NEW Strings.

You can get it to print out however you want. Are you hoping to have something execute it as code? That's a completely different story.

Yes I am wanting to send the string to an Arduino NanoESP32 running MicroPython to be executed.

Thanks for the reply. How do you mean to add a second print line?

Why will the program run out of memory, I only want to send some new code now and again? That's what we hobbyists do daily with our Arduinos, isn't it?

You might be better off using some sort of file system since Python is so reliant on formatting.

All depends on the number of times your program creates or modifies a "String". Strings are never changed in place they can ONLY be created new and that uses some memory. The used memory is never reclaimed until you execute the program the next time or your program ends.

What you describe in your original post would look a little different using Micropython, the Micropython code

"import machine\nimport utime\n\ngpio0 = machine.Pin(0, machine.Pin.OUT)\ngpio45 = machine.Pin(45, machine.Pin.OUT)\nutime.sleep(1)\ngpio45.value(0)\ngpio0.value(1)";

is something that you can enter via the REPL, you should know about the REPL if you have not come across the REPL yet do a search to get familiar.

It is possible to create a desktop app with your own REPL or there is a debugging tool called aiorepl which allows you to modify and query a running application.

So the answer to your original question is yes you can but it would help to know what you want to achieve and if you have a particular reason why you would want to do that.

But as you can see from the OP, the serial monitor does format the code if the string is included (as a string) in the sketch. It is only the string that is inputted that isn't formatted. What I want to achieve is to send MicroPython code to a device running MicroPython. I can do this, for instance, with the response from the OpenAI API or by including the string in the sketch, so why can't I do it with a string inputted via the monitor?

You can input code via the monitor but not the Arduino IDE serial monitor, the Arduino IDE is used for c\c++ .

Also you need a monitor/terminal that recognizes and responds to Ctrl A CtrlB CtrlC CtrlD , this keyboard input does things like break enter Raw REPL , exit Raw Repl reboot etc.

Give a simple example of what you would like to see so we can see if it is possible.

Which IDE do you use for Micropython.

I use the Arduino Lab for MicroPython to program my MicroPython devices and do not have a problem in this area.

I'm afraid you seem to have misunderstood my issue, probably my fault for mentioning MicroPython, but my problem is getting the Arduino IDE 2.3.2 serial monitor to recognize the \n in the string and put the following input on a new line. Just like the serial monitor does with a string in a sketch. I can't really explain it better than I did in the OP if you ignore the references to MicroPython, so I have edited the OP to remove the MP references.

The Serial monitor has nothing to do with it. Your sketch needs to recognise the \n in the String and print a Newline at that point

Read each character in the String and print it until you get a backslash. Do not print it. If the next character is a "n" then do not print it, print a Newline instead

You said ignore the reference to Micropython so what is this about?

I'm sorry if I'm being obtuse, but the sketch works perfectly with the string as included in the sketch:

    String codeString = "import machine\nimport utime\n\ngpio0 = machine.Pin(0, machine.Pin.OUT)\ngpio45 = machine.Pin(45, machine.Pin.OUT)\nutime.sleep(1)\ngpio45.value(0)\ngpio0.value(1)";
    Serial.println(codeString);

This gives the following in the monitor:

import machine

import utime

gpio0 = machine.Pin(0, machine.Pin.OUT)

gpio45 = machine.Pin(45, machine.Pin.OUT)

utime.sleep(1)

gpio45.value(0)

gpio0.value(1)

Which is what I want from the input string "import machine\nimport utime\n\ngpio0 = machine.Pin(0, machine.Pin.OUT)\ngpio45 = machine.Pin(45, machine.Pin.OUT)\nutime.sleep(1)\ngpio45.value(0)\ngpio0.value(1)"

Out of interest, have you managed to do that using Python code hard coded into the sketch ?

Yes, it works with the string shown above perfectly! I can also do it wth the response from OpenAI API. I just can't figure out how to format the input from the serial monitor.

Try this naughty sketch

String input = "";

void setup()
{
    Serial.begin(115200);
}

void loop()
{
    if (Serial.available())
    {
        input = Serial.readStringUntil('\n');
        formatInput();
    }
}

void formatInput()
{
    int index = 0;
    while (index < input.length())
    {
        if (input.charAt(index) != '\\')  //note use of escape character
        {
            Serial.print(input.charAt(index));
            index++;
        }
        else
        {
            Serial.println();
            index += 2;  //skip past next character whatever it is !
        }
    }
}

1 Like

Thank you, I think you are on the right track, but actually the string that gets printed DOES have the \n characters as can be seen from the monitor output in the OP. The \n that is thrown away is right at the end, the "\n"s within the "..." are retained but ignored, it seems.

That seems to work! Thank you very much. I need to have a good look at it tomorrow as it is past midnight here and I need to go to bed. I will mark it as the solution tomorrow.

BTW, why is it naughty?

At the very least it ought to check whether the character after the "\" is an "n". As it is, the character is always ignored whatever it is

There is a chance that the "\" character will be in the String and that it should not be ignored and/or neither should the next character

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.