How to creat printf with slightly different name - serial-port

I am using ATmega128 and I need two serial ports for communication. I have been using printf from "stdio.h" header file to send data through USART 0. I also need to send data through USART 1 to lcd and I am curious about using formatted input function. I have been thinking that connecting same printf function to USART 1 and USART 0 makes the compiler confused so I haven't tried it.
Can anyone suggest how to make another printf say "Lprintf" to send data through USART 1 ??

What you want to do here is to use fprintf(). See the documentation on avr-libc for the function. Essentially, you want to have a fputc() function for UART1 and one for UART0. Then, based on that, you can create two FILE buffers. Once you do so, you are free to use fprintf() on each. Optionally, you can point stdout to one of these buffers, as to be able to use printf().
FILE uart1_out = FDEV_SETUP_STREAM(uart1_putc, 0, _FDEV_SETUP_WRITE);
FILE uart0_out = FDEV_SETUP_STREAM(uart0_putc, 0, _FDEV_SETUP_WRITE);
fprintf(&uart1_out, "printing to UART1");
fprintf(&uart0_out, "printing %d to UART0", 0);
stdout = &uart1_out;
stderr = &uart0_out;
printf("This string will be printed thru UART1");
fprintf(stderr, "This string will be printed thru UART0");
You just need to provide the implementation for int uart1_putc(int, FILE*) and int uart0_putc(int, FILE*) to manipulate data as you wish.
Hope this helps.
Cheers.

Depending on how you've linked it, there are two alternatives that are possibly simpler:
Use sprintf() to write your formatted text to a string, and then use your own putchar() or putstring() to send it to the desired USART.
If you're using the FILE struct to link your USARTs to the stdio functions (likely), you can use fprintf() to direct the results to a particular stream.

Related

replicate Arduino's serial monitor on Scilab consol

If I use the Arduino IDE's Serial monitor I can read the pair of comma separated values as below:
I want to first replicate this behavior in SciLab terminal. I used the Serial Communication Toolbox:
h = openserial(7, "9600,n,8,1") // open COM7
disp(readserial(h))
closeserial(h)
which returns either empty or
, 169
228, 179
228,
228, 205
228, 209 228,
putting the disp(readserial(h)) in a while loop also doesn't help. Not only there are too many empty lines, if I stop the while loop it does not close the port (something like try-catch should be used I think). I would appreciate if you could help me know how I could get the same behavior as Arduino's serial monitor?
P.S. Next I want to plot these two values in realtime. So maybe using the csvTextScan function to split the string into two integers.
OK, after a couple of days struggling I figured this out. It turns out that SciLab doesn't have native serial communication functionality and the Toolbox developer has used TCL_EvalStr to run Tcl commands externally. I had to dig into the Tcl serial communication syntax (i.e. read, open, gets, fconfigure ... ), ask another question, get some help and then finally end up with a new function for the Toolbox which I have committed as a pull request:
function buf = readserialline(h)
tmpbuf = emptystr();
while tmpbuf == emptystr()
TCL_EvalStr("gets " + h + " ttybuf");
tmpbuf = TCL_GetVar("ttybuf");
end
buf = tmpbuf;
endfunction
now one can get the above behavior by running:
h = openserial(7, "9600,n,8,1") // open COM7
for ii = 1:40
disp(readserialline(h))
end
closeserial(h)
to read the serial port line by line and print it to the SciLab console. Now to parse the CSV data you may use:
csvTextScan(part(readserialline(h), 1:$-1), ',')
P.S.1. I have used a virtual Arduino board inside SimulIDE and used com0com to create virtual serial ports. More information here on SourceForge.
P.S.2. More discussion with Toolbox developer Aditya Sengupta here on Twitter.
P.S.3. More discussions here on Tcl Google group
P.S.4. A full demonstration plus instructions here on Reddit
P.S.5. For those who might end up here, I have decided to rewrite Aditya Sengupta's repository here with several improvements.

With Qt, how to check if stdin is empty?

I have a Qt program that processes stdin data like this:
QTextStream qtin(stdin);
QString stdindata = qtin.readAll();
QByteArray ba;
ba = stdindata.toUtf8();
QJsonDocument exJSONDoc(QJsonDocument::fromJson(ba));
QJsonObject extRoot;
extRoot = exJSONDoc.object();
QStringList keys;
keys = extRoot.keys();
for (int n=0; n <= keys.count()-1; n++)
{
qDebug() << extRoot.value(keys[n]).toString();
}
It works when I call my program like this:
myprogram < ./data.json
But if I call it without any "<" it hangs in qtin.readAll().
How can I check with Qt if the stdin is empty?
(I am assuming a Linux -or at least POSIX- operating system)
QTextStream qtin(stdin);
QString stdindata = qtin.readAll();
This would read stdin till end-of-file is reached. So works with a redirected input like
myprogram < ./data.json
But if I call it without any "<" it hangs ...
But then (that is, if you run myprogram alone) stdin is not empty. It is the same as your shell's stdin. and your program, being the foreground job, is waiting for input on the terminal you are typing (see also tty(4)). Try (in that case) typing some input on the terminal (which you could end with Ctrl D to make an end-of-file condition). Read about job control and the tty demystified and see also termios(3).
Perhaps you could detect that situation with e.g. isatty(3) on STDIN_FILENO. But that won't detect a pipe(7) like
tail -55 somefile | myprogram
You need to define what an empty stdin is for you. I have no idea what that means to you, and I would instead think of myprogram < /dev/null (see null(4)) as the way to get an empty stdin.
Perhaps you should design myprogram so that some program
option (perhaps --ignore-stdin) is avoiding any read from stdin.
Problem here is readAll. See documentation:
Reads the entire content of the stream, and returns it as a QString.
Avoid this function when working on large files, as it will consume a
significant amount of memory.
So it reads stdin until it encounters end of file and since stdin is associated with console you have to signal end of file. Usually it is Ctrl-D and press enter.
It is more probable you what to read stdin line by line.
To alow user text editing console transfers data to standard input of the application only line by line. This was designed like this ages ago when computer had only a printer as user interface (no screen).
Now question is how to read JSon form stdin console connected with console without end of file information?
I would use some SAX parser, but this would be to complicated for you.
So is there another way to detect end of JSon?
You can try this approach (this is basic idea, not final solution, so it has couple shortcomings):
QFile file(stdin);
QByteArray data = file.peak(largeNumber);
QJsonParseError error;
QJSonDocument doc = QJSonDocument::fromJson(data, &error);
while (!doc.isValid() && JSonNotTerminatedError(error.error))
{
// TODO: wait for new data - it would be best to use readyRead signal
doc = QJSonDocument::fromJson(data, &error);
}
Where JSonNotTerminatedError returns true for respective QJsonParseError::ParseError values (see linked documentation) which are related with unterminated JSon data.
Now I see QFile doesn't have required constructor, but main concept should be clear. Read data from stdin and check if it is a valid JSon document.

Scapy raw data manipulation

I am having troubles manipulating raw data. I am trying to change around a
resp_cookie in my ISAKMP header and when I do a sniff on the packet it is all in raw data format under Raw Load='\x00\x43\x01........... ' with about 3 lines like that. When I do a Wireshark capture I see the information I want to change but I cant seem to find a way to convert and change that raw data to find and replace the information I am looking for. Also, I can see the information I need when I do a hexdump(), but I can't store that in a variable. when I type i = hexdump(pkt) it spits out the hexdump but doesn't store the hexdump in i.
So this post is a little old, but I've come across it a dozen or so times trying to find the answer to a similar problem I'm having. I doubt OP has need for an answer anymore, but if anyone else is looking to do something similar...here you go!
I found the following code snippet somewhere in the deep, dark depths of google and it worked for my situation.
Hexdump(), show() and other methods of Scapy just output the packet to the terminal/console; they don't actually return a string or any other sort of object. So you need a way to intercept that data that it intends to write and put it in a variable to be manipulated.
NOTE: THIS IS PYTHON 3.X and SCAPY 3K
import io
import scapy
#generic scapy sniff
sniff(iface=interface,prn=parsePacket, filter=filter)
With the above sniff method, you're going to want to do the following.
def parsePacket(packet):
outputPacket = ''
#setup
qsave = sys.stdout
q = io.StringIO()
#CAPTURES OUTPUT
sys.stdout = q
#Text you're capturing
packet.show()
#restore original stdout
sys.stdout = qsave
#release output
sout = q.getvalue()
#Add to string (format if need be)
outputPacket += sout + '\n'
#Close IOStream
q.close()
#return your packet
return outputPacket
The string you return (outputPacket) can now be manipulated how you want.
Swap out .show() with whatever function you see fit.
P.S. Forgive me if this is a little rough from a Pythonic point of view...not a python dev by any stretch.

`fprintf` with SD.h's File type

I'm using the SD.h library to write onto an SD card with the Arduino Uno. I need to write out in a file a template string with some placeholder replaced by certain values, in the way of printf behaves. I would use the fprintf function, but when I tried this:
File dataFile = SD.open("myfile.txt", FILE_WRITE);
fprintf(dataFile, "mynumber: %d\n", 100);
I got this error:
cannot convert 'File*' to '__file*' for argument '1' to 'int
fprintf(__file*, const char*, ...)'
How can I manage this?
printf() makes your executable object ~1000 bytes larger, so you may not want to use it if size is a problem.
The fprintf is not intended to use with the SD.h so I think
The simple solution that comes into my mind is using sprintf to format your text then write it to the file with the println function
File dataFile = SD.open("myfile.txt", FILE_WRITE);
char text[100];
sprintf(text,"My number: %d",yournumber);
dataFile.println(text);

Unix write() function (libc)

I am making a C application in Unix that uses raw tty input.
I am calling write() to characters on the display, but I want to manipulate the cursor:
ssize_t
write(int d, const void *buf, size_t nbytes);
I've noticed that if buf has the value 8 (I mean char tmp = 8, then passing &tmp), it will move the cursor/pointer backward on the screen.
I was wondering where I could find all the codes, for example, I wish to move the cursor forward but I cannot seem to find it via Google.
Is there a page that lists all the code for the write() function please?
Thank you very much,
Jary
8 is just the ascii code for backspace. You can type man ascii and look at all the values (the man page on my Ubuntu box has friendlier names for the values). If you want to do more complicated things you may want to look at a library like ncurses.
You have just discovered that character code 8 is backspace (control-H).
You would probably be best off using the curses library to manage the screen. However, you can find out what control sequences curses knows about by using infocmp to decompile the terminfo entry for your terminal. The format isn't particularly easy to understand, but it is relatively comprehensive. The alternative is to find a manual for the terminal, which tends to be rather hard.
For instance, I'm using a color Xterm window; infocmp says:
# Reconstructed via infocmp from file: /usr/share/terminfo/78/xterm-color
xterm-color|nxterm|generic color xterm,
am, km, mir, msgr, xenl,
colors#8, cols#80, it#8, lines#24, ncv#, pairs#64,
acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
bel=^G, bold=\E[1m, clear=\E[H\E[2J, cr=^M,
csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H,
cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C,
cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A,
dch=\E[%p1%dP, dch1=\E[P, dl=\E[%p1%dM, dl1=\E[M, ed=\E[J,
el=\E[K, enacs=\E)0, home=\E[H, ht=^I, hts=\EH, il=\E[%p1%dL,
il1=\E[L, ind=^J,
is2=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8, kbs=^H,
kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA,
kdch1=\E[3~, kf1=\E[11~, kf10=\E[21~, kf11=\E[23~,
kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, kf15=\E[28~,
kf16=\E[29~, kf17=\E[31~, kf18=\E[32~, kf19=\E[33~,
kf2=\E[12~, kf20=\E[34~, kf3=\E[13~, kf4=\E[14~,
kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~,
kfnd=\E[1~, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
kslt=\E[4~, meml=\El, memu=\Em, op=\E[m, rc=\E8, rev=\E[7m,
ri=\EM, rmacs=^O, rmcup=\E[2J\E[?47l\E8, rmir=\E[4l,
rmkx=\E[?1l\E>, rmso=\E[m, rmul=\E[m,
rs2=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8, sc=\E7,
setab=\E[4%p1%dm, setaf=\E[3%p1%dm, sgr0=\E[m, smacs=^N,
smcup=\E7\E[?47h, smir=\E[4h, smkx=\E[?1h\E=, smso=\E[7m,
smul=\E[4m, tbc=\E[3g, u6=\E[%i%d;%dR, u7=\E[6n,
u8=\E[?1;2c, u9=\E[c,
That contains information about box drawing characters, code sequences generated by function keys, various cursor movement sequences, and so on.
You can find out more about X/Open Curses (v4.2) in HTML. However, that is officially obsolete, superseded by X/Open Curses v7, which you can download for free in PDF.
If you're using write just so you have low-level cursor control, I think you are using the wrong tool for the job. There are command codes for many types of terminal. VT100 codes, for example, are sequences of the form "\x1b[...", but rather than sending raw codes, you'd be much better off using a library like ncurses.

Resources