Retrieve data from COM port using a batch file - batch-file

I'm trying to automatically retrieve data from a COM port using a batch file.
I'm able to configure the com port and to send the command in other to ask my device for the info.
The problem is that I'm not able to capture the data that the device sends. I've tried with RealTerm and the device is working and sends the info back to the pc, but I really need the batch file to do it automatically, here is the code:
echo off
MODE COMxx ...
COPY retrievecommand.txt \\\\.\COMxx:
COPY \\\\.\COMxx: data.txt
Any suggestions?

Use the TYPE command in a recursive loop using the DOS GOTO command to a DOS LABEL. Use 'append output' to capture text like TYPE COM1:>>Data.txt The double > means continually concatenate (or append) to Data.txt. A single > or 'redirect output' would replace the text in Data.txt every loop (if com data present on port). Add a 2nd line that redirects to the monitor screen so you can watch activity too (i.e. TYPE COM1:>CON [CON means console or monitor screen but you can omit it as console is default anyway])
Control-Z is not needed by TYPE command. It will just dump text continually until operator does a Control-C and then a Y to break the loop. You really don't need to stop the loop unless you are done with the batch file all together. The Data.txt file will be available to other programs live and will not present a 'Sharing Violation' if you try to access it with another program like NOTEPAD.EXE while this batch file is still looping.
Also if you make a 3rd line in the batch file that says TYPE COM1:>Data1.txt [notice only one redirect], you will have a single line of instant text that will disappear with next iteration. But sometimes that is helpful if you need only one line of data. There are creative ways to extract one line of data to another text file using the DOS FIND command.

When reading, the COPY command will continue until it detects the end of file. As the source is a device (with a potentially infinite stream) it only knows to stop when it detects an end of file marker. This is the Ctrl-Z (0x1A) character.
The suggestion in the duplicate question of using the TYPE command to read is likely to result in the same problem.
There is no standard mechanism to read a single line. If you can port your application to PowerShell, you should be able to read single lines with the results you expect.

Related

Is there any way of storing a command written in prompt into JSON file

I am using ubuntu and i have used a library named as ICLI (interactive command line interface) which lets one build his own prompt. and i want whatever command i write in this prompt to be stored as JSON.
One way of doing so is file write, for which you can try
with open("data_file.json", "w") as write_file:
json.dump(data, write_file)
Here, data is a variable created before writing these lines. data contains whatever information needs to be stored, in JSON format.

Access watch variables from trace32 scripting language

I'd like to create a diagnosis script and would like somehow to get all the variables the user inputs in a watch window to a script. How may i access the watch variables and manipulate them?
I tried with a DIALOG.view but that wastes too much time. There might be another trace command but I don't know it. Thank you!
Getting the content of open Var.Watch windows from script is not directly supported in TRACE32.
However you can do the following in you script
Redirect printing to a file PRinTer.FILE "~~~/winpage.txt" ASCIIE (of course you can choose any other filename instead of winpage.txt)
The window WinPAGE.List shows you all open child windows. With WinPrint.WinPAGE.List you can sent the list of all open windows to the file specified before (winpage.txt).
Now parse the content of winpage.txt for the names of the windows, which are a watch windows. The window names start by default with a capital 'W' followed by three decimal digits (but can also be totally different) and are then followed by the command (in round brackets) which was used to open the windows. Compare case insensitive!
The watch windows have a command which starts with:
B::Var.Watch
B::V.Watch
B::Var.W
B::V.W
Redirect printing to a new file e.g. PRinTer.OPEN "~~~/varwatch.txt" ASCIIE
Send the content of each open watch window to the file varwatch.txt with the command WinPRT <window name>. The relevant window names you've got from step 3. Execute WinPrt for each open watch window.
Close varwatch.txt with PRinTer.CLOSE
Now you should have the content of all open watch-windows in the file varwatch.txt.
Other idea:
Use command STOre "mywindows.cmm" Win to save commands to create all open windows to a script.
Parse this script for all lines starting with Var.Watch (or one of it's shorts forms) and the lines starting with Var.AddWatch (or one of it's shorts forms). Parse case insensitive!. The arguments followed by Var.Watch or Var.AddWatch are the variables currently shown in the watch windows.

Can i create a gcode that self destructs after one instance of printing?

Can i create a gcode that self destructs after one instance of printing? For example I send the gcode created to a printer at a remote area to print but I want them to only print it once. Can i add a self destruct code so that it deletes after running once?
No, sorry, you cannot. There is no GCODE command for self-destruct of the file (or command stream) and the GCODE commands can be processed by any number of recieving applications and firmwares. Some work on files, others work on command streams, and some can use GCODE in either a stream or a file. So there's no way to force the receiving app/firmware to delete the file or stream.
Everything depends on which firmware your printer is using. "Gcode" is interpreted differently on different printers.
Marlin is a very popular firmware and runs on nearly every entry-level printer, such as Creality printers (CR-10, Ender 3, etc), Wanhao/MP MakerSelect, etc.
You can find a full documentation of every available gcode command here: https://marlinfw.org/meta/gcode/
With that said, not all GCode commands are implemented by every printer. Some printers trim out GCODE that isn't commonly used to keep the firmware file small, thus allowing them to make the "brains" of the printer with a cheaper microcontroller.
There IS a delete from SD card option, the code is "M30" and is documented here: https://marlinfw.org/docs/gcode/M030.html
Your printer may not support this though, so you'll have to test it out yourself.
The usage is:
M30 /path/to/file.gco
You'll have to know the path to the file, and this relies on your path not changing, so it may not be very practical. This command is generally something used by someone issuing commands to a printer manager, not something you should be sticking at the end of a gcode file to self-destruct.

Stable text feed for vim through vimserver

I am searching for a highly stable way to feed text (output of a program) into vim through vimserver. Assume that I have started a (g)vim session with gvim --servername vim myfile. The file myfile contains a (unique) line OUT: which marks the position where the text should be pasted. I can straight forwardly achieve this from the commandline with vim --servername vim --remote-send ':%s/OUT:/TEXT\\rOUT:/<Enter>'. I can repeatedly feed more text using the same command. Inside a C-program I can execute it with system(). However TEXT which is dynamic and arbitrary (received as a stream in the C-program) needs to be passed on the command line and hence it needs to be escaped. Furthermore using the replacement command %s vim will jump to the position where TEXT is inserted. I would like to find a way to paste large chunks of arbitrary text seamlessly in vim. An idea is to have vim read from a posix pipe with :r pipe and to write the the string from within the C-program to the pipe. Ideally the solution would be such that I can continuously edit the same file manually without noting that output is added at OUT: as long as this location is outside the visible area.
The purpose of this text feed is to create a command line based front end for scripting languages. The blocks of input is entered manually by the user in a vim buffer and is being sent to the interpreter through a pipe using vim's :! [interpreter] command. The [interpreter] can of course write the output to stdout (preceded by the original lines of input) in which case the input line is replaced by input and output (to be distinguished using some leading key characters for instance). However commands might take a long time to produce the actual output while the user might want to continue editing the file. Therefore my idea is to have [interpreter] return OUT: immediately and to append subsequent lines of output in this place as they become available using vimserver. However the output must be inserted in a way which does not disturb or corrupt the edits possibly made by the user at the same time.
EDIT
The proposed solutions seem to work.
However there seem to be at least two caveats: * if I send text two or more times this way the `` part of the commands will not take me back to the original cursor position (if I do it just once still the markers are modified which may interrupt the user editing the file manually) * if the user opens a different buffer (e.g. the online help) the commands will fail (or maybe insert the text in the present buffer)
Any ideas?
EDIT: After actually trying, this should work for you:
vim --servername vim --remote-send \
":set cpo+=C<CR>/OUT:<CR>:i<CR>HELLO<CR>WORLD<CR>.<CR>\`\`"
As far as I can see, the only caveats would be the period on a single line, which would terminate :insert instead of being inserted, and <..> sequences that might be interpreted as keypresses. Also, need to replace any newlines in the text with <CR>. However, you have no worries about regular expressions getting muddled, the input is not the command line, the amount of escaping necessary is minimal, and the jumping is compensated for with the double backticks.
Check out :help 'cpoptions', :help :insert, and :help ''.
Instead of dealing with the escaping, I would rather use lower-level functions. Use let lnum = search('^OUT:$') to locate the marker line, and call setline(lnum, [text, 'OUT:']) to insert the text and the marker line again.

What are possible reasons that cmd stop writing to a file with redirection?

This is on win7.
I got a batch script that executes a C++ program and take all of its output to the file with ">".
The program takes input from servers and display everything. We need all these information so we log all these outputs down to a file. But after a short while, we see that the program stops writing to the file and just stop there while the program continues running.
The file size is also at 0 byte (OS doesn't update until file is closed?) But we can see the content of the file with notepad++, but it does not seem to update any longer.
There are about 250,000 lines long and we see that our data simply got cut off in the end. For example, suppose you should have a table of data that lists out 123 567 436 975, we only see 123 567 43. The whole line isn't even finished in the end.
There are a lot of things to write down and there are lots of network transmission. Does the program simply give up outputting when there are too much data? Is there a way around this?
Try to disable buffering. setbuf(stdout, NULL);.
Anyway, in new versions of windows, when a file is being created and data is being written (the clasic >file scenario), the grow of the file is not always visible.
In this case, dir command shows a 0 bytes file, or stops to show increasing values.
Try to read the file with type file >nul and then dir file. This "should" refresh the file size information. But it is not needed. The file is growing, just not showing it.

Resources