I have been searching this, but couldn't get a good answer.
i have to send a file through COM port between two PC.
but i dont know how to detect the end of file.
In PC 1 i use teraTerm software to send file.
In PC 2 is use the following python code.
After the file is sent i need to put some message that the file is complete.
import serial
ser = serial.Serial('COM1')
ser.flush_input_buffer()
file = open('file.txt','a') #open empty file for appending
while True:
receivedByte = ser.read() # read 1 byte
file.write(receivedByte)
if (#detect end of file ):
break
print('file received')
Please note : PC is windows 8.1, Pyserial, Python 3.4
Please also suggest for Linux file
There is no EOF for a serial port as such. And what I can gather from the Internet teraTerm doesn't have a protocol for sending files, but just sends them in their raw form.
You could maybe set the read timeout for the serial port, so that the read would raise a SerialTimeoutException when there is no data left.
I tried this solution, although it is not as elegant and rather simple. It does work.
receivedByte = ser.read() # read 1 byte
while receivedByte != b'':
file.write(receivedByte)
receivedByte = ser.read()
print('file received')
Related
The latest documentation for serial communication in Octave explains to use the "serialport" command to open the port instead of the deprecated "serial" command.
https://octave.sourceforge.io/instrument-control/overview.html
There is no explanation of how to close the serial port. I used this to successfully open the port and do some writing
s1=serialport('com5','Baudrate',57600)
num=write(s1,'help')
But I can't figure out how to close the port. I used this:
fclose(s1)
And got this error response
error: file id must be a file object, std::string, or integer value
Does anyone know how to close the serial port?
The octave functions attempt to mimic where possible the Matlan functions, which also does not have a close function.
To close the serial port, set the variable to something else, and if it is not used elsewhere, it will close the port.
# create a serialport references by the s1 variable
s1=serialport('com5','Baudrate',57600)
num=write(s1,'help')
# set s1 to something else
s1 = [];
# s1 was only variable referencing the serial port
# so the serial port is now freed/closed
You could also clear the variable:
clear s1
I am trying to make a windows executable talk with a Quectel module through serial.
The tool always fails at the first step which is to read the module's firmware version with an AT command (AT+CGMR\r).
I tested to send the same command to the module, using Putty and typing out the command, and it worked like a charm.
However, when I type the command in a notepad (including the carriage return at the end), then copy the text and paste it into putty (my idea was to get closer to the behavior of the .exe by sending the command faster), 2 weird things happen:
1 - I don't get a response from the module until I send a second carriage return by pressing Ctrl-M in putty. I am certain that the character is copied into the clipboard from the notepad though...
2 - The module does not receive "AT+CGMR" but "AT+CGMM" (which is also a valid command). I tested other variations and concluded that the last text character is always replaced by the second to last text character. So AT+CDFR gives AT+CDFF. AT+PILJ gives AT+PILL etc...
I am certain that is what the module receives because echo mode is on so the module prints out the command it received before the answer to said command.
To summarize:
By typing on the keyboard directly into putty I get:
AT+CGMR
SSB,V150R100C10B200SP1
SECURITY_A,V150R100C20B300SP5
PROTOCOL_A,V150R100C20B300SP5
APPLICATION_A,V150R100C20B300SP5
SECURITY_B,V150R100C20B300SP5
RADIO,Hi2115_RF0
OK
Which is the expected output.
But by copying and pasting the exact same text from notepad I get:
AT+CGMM
BC95GJB-02-STD
OK
and that, only after I press Ctrl-M. Before that there is no answer at all so it is as if the module never received the carriage return.
I can't figure out what is going on here... Any help appreciated.
I worked a lot with Quectel 4G modules. Maybe make a simple data tracer.
Download dumb terminal Termite so you can see single hex characters including non printable. Connect termite to to read a stock USB to serial adaptor. Make sure the adaptor is set to 3.3V not 5V. The Quectels are 1.8V domain but can scrape in and drive 3.3V logic. I assume you are driving your Quectel with 1.8V.
Hardware wise attach the Rx pin of the Quectel module to the USB module Rx pin then you can see exactly the characters going into the Quectel from Notepad and Putty. (Sometimes you may need a 1K in series with the USB Rx pin to reduce loading). Bingo, you can see exactly the characters the Quectel is getting. I found many bugs doing this.
I'm having problems sending an echo to an a RFID reader. In one terminal I'm running a cat like cat < /dev/ttyUSB0 and in another one I'm sending an echo like echo $'\x80\x80\x80\x01\x01\x01\x11\x14' > /dev/ttyUSB0, where the bytes are the command for initializing the reader. Nothing happens...
The RFID readers come with an specific software that actually make them work. But when I want to replicate the same behavior with my programe, I can not get it to work.
My hypothesis is that maybe the echo is not actually writing the bytes to the serial port, and maybe all the data is stored somewhere waiting for some kind of another signal.
I know that the question is not quite specific, but I only want to know if maybe I'm ignoring some basic stuff related to serial communication.
Thanks.
these are the write commands towards a serial port:
sendCommand(SendCOM3,"hallo\r\r") --- text format
sendCommand(SendCOM4,"\u0001\u0012\u0123\u000F\r\r") --- binary format
and works fine.
Now, who can tell me what I have to do to get the response message over the same serial port ?
Thanks
Ciao
marco
Since you're already writing to the port, I'm assuming you have the serial binding as an addon and the serial ports enabled.
Create a new item and bind it to the serial port to assign incoming data. For example,
String Hallo1 "Hallo [%s]" (hall0) {serial="SendCOM3"}
The data is a string that you'll need to parse. Restart OpenHAB, check the logs and you should see your item updated.
Add serial binding .jar file to your addons directory
org.openhab.binding.serial-1.7.1.jar
And add item to yourschema.items:
String MySerialDevice "MySerialDevice [%s]" { serial="/dev/ttyUSB0" }
change ttyUSB0 to your real tty serial device.
I've got an Arduino attached to my Raspberry Pi which runs on Archlinux ARM, and I'm using a simple C program that reads and writes to the serial bus to the Arduino (/dev/ttyACM0).
This worked fine as long as I had the Arduino attached to my PC, but when I use the Raspberry Pi instead, reading still works but writing will freeze as soon as the buffer is flushed or the connection closed.
This very basic C example atually causes such a freeze:
If the fflush() command is in there it will freeze there, if it's removed then it'll instead freeze at fclose().
FILE *fp;
fp = fopen("/dev/ttyACM0", "wb");
..error handling..
fprintf(fp, "%c", 'B'); /* write the character 'B' to the serial port)
fflush(fp); /* optional, if more write operations follow, in an actual program */
fclose(fp);
Reading from the bus works fine.
I also tried the program "minicom" as it is often suggested for testing serial connections, and it yielded the same results: Sending from Arduino to Pi is fine, trying to type in a character on Pi side -> freeze.
I have tried lots of different stuff on opening/configuring such as replacing the simple fopen() sequence shown above by:
fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
fcntl(fd, F_SETFL, 0);
if (fd == -1) {
printf("couldn't open serial port.\n");
return -1;
}
fp = fdopen(fd, "w");
and also changing some canonical something parameters (not sure what I'm actually doing there) but to no avail. It will just keep freezing as soon as the Pi tries to write a character to the serial bus.
I've also made sure that all TTYs are unused on the Pi via
ps -ef | grep -i tty
to exclude any silly getty/agetty interference.
And I've tested it without any additional hardware plugged in, to make sure that it isn't a symptom caused by the power supply not being able to sustain everything connected to the Pi, as someone suggested to me.
By now I'm totally out of ideas except that the hardware is maybe just faulty. But that's hard to believe, is it? (And I don't have a replacement to test.)
UPDATE:
When using above alternate sequence and removing the fcntl() line, the C program no longer freezes on writing:
fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
printf("couldn't open serial port.\n");
return -1;
}
fp = fdopen(fd, "w");
So at first I was happy, but actually the written data never arrives on the Arduino side! :(
first of all, rasPI cannot work directy from a PC USB as they are limited below the rasPI need, so you need an external power supply (i used one from a smartphone, now i'm using a plugged usb hub)
Changes are that plugging your arduino drains too much power, and the arduino's and rasPi chip beave randomly. Check if, when the program freeze, the serial port used is still there (check with dmesg, maybe it has been plugged/uplugged)
If your power source are fine, then explain what you mean by freeze; the rasPi freeze or only the code. Eiter case it is a fault on the rasPi side, try updating OS and firmware; the serial does not check if someone is reciving, so flush should only hang the time necessary to write the buffer, even if no one is reading.
remeber that close(), will always call flush(), so use flush() only if really needed. (like in this case, for debugging purpoise :) )