Writing to Linux text file from sketch Issue

I am learning to use my UNO Q. Worked up a sketch and a python script with help of AI and some docs digging.

Arduino sketch:

<CODE>

#include <Arduino_RouterBridge.h>

bool result = false;
void setup() {

Bridge.begin();
Monitor.begin();
delay(5000);
Bridge.call("append_to_file", "/home/arduino/data.txt", "Hello from MCU").result(result);

if (result) {
    Monitor.println("Append successful");
} else {
    Monitor.println("Append failed");
}
}

void loop() {

delay(3000);
Bridge.call("append_to_file", "/home/arduino/data.txt", "Hello from MCU").result(result);
if (result) {
Monitor.println("Append successful");
} else {
Monitor.println("Append failed");
}
}

#main.py

from arduino.app_utils import App, Bridge

def append_to_file(filename: str, text: str):
"""Append text to a file on the Linux side."""
print(f"append to file routine")
try:
with open(filename, "a", encoding="utf-8") as f:
f.write(text + "\n")
print("Outside 'with': file closed?", f.closed) # Should be True
print(f"text written to {filename} {text}")
return True
except Exception as e:
print(f"Error appending to file: {e}")
return False

Bridge.provide("append_to_file", append_to_file)

def loop():
pass # No periodic work needed

App.run(user_loop=loop)

<CODE/>

All of the above appears to run after I click on RUN in AppLab and wait for the message that app is running. In the monitor I see the python messages indicating text has been written. I see the sketch messages that the append to file was successful or not.

As a note: I put in the python message regarding file closed just to be certain that it was closed (as docs say it should be) and buffers written out.

My problem is: I don't see the resulting data.txt file.

I checked arduino user permissions and they were okay. I wrote a short python script to write out a data.txt file and it worked, dummy text was written to the file. I also showed all the files with ls -a and data.txt isn't there.

I am at a loss as to why this app doesn't write out a file. I thought Bridge would allow a script to invoke a python function (append_to_file) to handle file update on the Linux side.

I have searched for clues to the problem, but to no avail. Any suggestions? Am I barking up the wrong tree?

Thanks

Where do you want to see "Hello from MCU" on Serial Monior or on Python Console?

Please, format your code of post #1 with code tags < code>.

This is my output on Python Console after running tour app:

text written to /home/arduino/data.txt Hello from MCU
append to file routine
Outside 'with': file closed? False
text written to /home/arduino/data.txt Hello from MCU

This is my output on Serial Monitor after running your app:

Append successful
Append successful

Thanks for your input and thoughts. To answer your question: I want to see an actual data.txt file in the /home/arduino folder. Sorry about the formatting. I used the <code> <code/> tags, but obviously incorrectly.

1.

Select the code block and then click on < code>.

2.

You have asked MPU/Linux to write "Hello from MCU" into a file named data.txt. Do you want to be sure that the data "Hello from MCU" has really been written into that file? If yes, then you have to add code to script to read the data from the file and send it back to MCU who will print it on Serial Monitor.

Thanks for clarifying. My intention is to retrieve this data.txt file at a later time. My current application writes to a microSD card, which I've found to be unreliable. I had planned to port the app to the UNO Q and take advantage of the Linux file system. Guess that's out of the question if I can never "see" where this data.txt file is stored.

I appreciate your input on this. I will need to rethink my approach to the problem of retrieving the file for later analysis.

Hi, may be a path problem, try to use just filename, then it should end in project home.

I have something like this in code

def on_post_settings(payload: dict = None):
    global startupConfig
    startupConfig = payload
    with open('settings.json', 'w') as settingsFile:
        settingsFile.write(json.dumps(startupConfig))
    try:
        push_settings()
    except Exception as e:
        print(f"Warning: could not push settings to sketch: {e}")

You have not answered to my queston and you have not leanred how o use < code> tgas. Thank syou.

I have not understood what is the problem of OP? Can you please, clarify to me.

BTW - thanks for explaining how to use the code tags to format properly. Will do so in the future when posting code.

Sorry, but I thought I had answered the question. Reading back what was sent to the file doesn't do what I need. I need to have a file that I can interrogate at a later time, essentially read it at that later time for analysis; and, possibly, write code to use the data.

I found in a different post the mention of docker and what it allows or doesn't allow. I haven't fully digested that yet, but that post indicated that the file won't actually be written. It seems to me, however, that calling a routine through Bridge from a sketch and writing to a file that one can never "see" or find makes no sense. I'd like to hear your opinion on that if you have time.

I have done for you here:

Sketch:

#include <Arduino_RouterBridge.h>

bool result = false;

void setup() 
{
   Bridge.begin();
   Monitor.begin();
   delay(5000);
   Bridge.call("append_to_file", "/home/arduino/data.txt", "Hello from      MCU").result(result);

   if (result) 
   {
      Monitor.println("Append successful");
   } 
   else 
   {
      Monitor.println("Append failed");
   }
}

void loop() 
{
   delay(3000);
   Bridge.call("append_to_file", "/home/arduino/data.txt", "Hello from MCU").result(result);
   if (result) 
   {
      Monitor.println("Append successful");
   } 
   else 
   {
      Monitor.println("Append failed");
   }
}

Script:
#main.py

from arduino.app_utils import App, Bridge

def append_to_file(filename: str, text: str):
   """Append text to a file on the Linux side."""
   print(f"append to file routine")
   try:
      with open(filename, "a", encoding="utf-8") as f:
      f.write(text + "\n")
      print("Outside 'with': file closed?", f.closed) # Should be True
      print(f"text written to {filename} {text}")
      return True
   except Exception as e:
      print(f"Error appending to file: {e}")
      return False

Bridge.provide("append_to_file", append_to_file)

def loop():
    pass # No periodic work needed

App.run(user_loop=loop)

I have not yet understood what you want to achieve?

Form post #1, I understand that you want to test the following:
1. You pass a file name = data.txt from MCU to MPU.

2. You have passed a director name = `/home/arduino/' from MCU to MPU.

3. You passed a data = Hello from MCU from MCU to MPU.

4. You have written a script which will create the said file (1.) under the given directory (2.) and then will put the data (3.) into that file.

5. You want to read back the data from the file and show it on Serial Monitor.

Can you see Helloo from MCU on your Serial Monitor?

6.

What do you mean by "interrogate?"

@davycastle

1. In the sketch, put code in setup() functon to check that Linux/MPU has started, place the remaining codes in the setup() function and ten proceed to loop() function.

Do you know how to properly use the result() method of the object retrurned by Bridge.call() function?

2. Do you know what is Docker and what is Container?

3. As you are traveling over the net to get code and code -- this is not going to help you. Try to undersand your need and place appropriate question in the forum to get help.

You have a good point. I am trying to learn how to use UNO Q. I am looking at code to learn from it. I know what container is and what docker means, though I am not intimate with either. My intention now that I've come across these in conjunction with my learning process is to research them further to get a full understanding.

Let me clarify a bit my end game.

I have developed an app using UNO R4. It is an electronic chessboard. Players use chess pieces that the board recognizes as black or white, king, queen, etc. As the players play the game, the moves are written to a PGN (portable game notation) file. This PGN file can then be loaded into a PGN viewer program for analysis -- good moves, patterns, bad moves and blunders.

The first version of the chessboard worked well. The second version improved on the hardware. My intention for a third version is two-fold:

  1. improve reliability of storing moves. The microSD cards have proven to be unreliable. If they fail at the beginning during the board's setup process, then I can reformat them and most likely all will be fine. If they fail -- become unreadable -- during the game, then the record of moves is lost. Using the Linux file system to write out the moves seems promising. I originally intended to port all the code to Python using a Raspberry Pi. When the UNO Q was announced, I decided to go with that.

The second thing I intend to accomplish with Version 3 of this board is the ability to play against the computer. My plan is to incorporate a simple chess engine, figure out how to have it understand the layout of the board (i.e. where all the chess pieces are) at each move, and come up with a move.

WHEN a move is complete -- both white and black have moved their pieces -- a line is written to the PGN file using standard chess notation. At the end of the game, the PGN file is loaded into a PGN viewer at some later time. That's why it is important to me to "see" the file that was just updated.

As I said, I am writing to microSD cards. I discarded the cheap ones and went with the more expensive cards. Still, these cards occasionally manifest errors. They become unreadable. My research on this issue has shown me that microSD cards are inherently unreliable. I don't know exactly why.

My example code was written using a TXT file simply because I am trying to get comfortable with the UNO Q, its Linux side, and APP LAB. I intend to look into CLI this weekend. Scouring the internet to find examples to learn from is the only real approach I know when learning something new. In all cases, I make know of the things like docker and containers that need further explanation and education on my part.

I should mention that getting sample code that doesn't work is just as helpful as code that does, especially if I can tweak it, check other docs, and make corrections.

All in all, I appreciate your input. If there's some documentation you know of that addresses my problem of "seeing" a file I just wrote to, please advise. I did write a short Python program to write a file -- outside of AppLab -- and that file was right where I expected it: The /home/arduino directory.

Again, thanks for the input.

Thank you very muc for taking the time to clarify the context.

I am still inerested to get the answer of Question-5 of post #13.

Question 5 of post 13 -- reading back the data from the file. As expressed in post 13:

You want to read back the data from the file and show it on Serial Monitor.

I have not yet tried to read back the data. Possibly, it is a bit of tunnel vision on my part because I've been tuned into the idea of "seeing" the file at /home/arduino. If the file was there, I'd take that as evidence that a PGN file in my program will be available at the end of the game.

If I read it back during my "educate me" phase (which I'm in right now) perhaps I will learn something; I will take your suggestion and do so.

But that's a task for tomorrow. It is close to midnight where I am, so time to sleep and tackle things anew tomorrow.

You can use cli command to see the directoy tree of Linux. You can also use cli command to see the connet of your data.txt file. Are you familiar with how to issue cli command from Shell terminal?

If you know fine; else, Gemini will guide you well.

Good night.

The problem may be the App Lab docker container prevents main.py from writing to /home/arduino.

If you do not need the App Lab bricks, run a program outside App Lab to collect the data and write to file in /home/arduino. The sketch can use TCP client to open a socket to a program running on the Linux side.

This demo sketch opens a TCP socket to port 31415 on localhost then writes a line of text once a second.

#include <Arduino_RouterBridge.h>

BridgeTCPClient<> tcpclient(Bridge);

void setup(){
  Bridge.begin();
}

void loop() {
  static uint32_t count = 0;
  if (tcpclient.connected()) {
    Serial.println("Sending to socket");
    tcpclient.print("Hello from sketch ");
    tcpclient.println(count++);
  }
  else {
    Serial.println("Socket not connected so try to connect");
    if (tcpclient.connect("127.0.0.1", 31415)) {
      Serial.println("Connected.");
    } else {
      Serial.println("Connection failed.");
    }
  }
  delay(1000);
}

Prerequisite: Understand Linux command line.

On the Linux side run a no-code test TCP server like this to see the output of the sketch.

nc -l -p 31415

When the sketch TCP client connects to nc (also known as netcat), nc reads from the socket and writes to stdout.

If all goes well, Hello from sketch <n> should appear once a second.

You can replace nc with your python program.

In Arduino App Lab, I have sketch.ino and my.py files. Under which directory of Linux are they lying? Is it under /home/arduino directory? Is it possible that I issue ls -a command from shell terminal and see the names of these files?