Is it possible to have AT+CMGS commands cancelled by some control code other than ESC?
I need it because ESC is intercepted by the attached equipment for its own use and never gets to the modem. And, I can't change that.
Unfortunately, CTRL-Z will send even an empty message, or else I could backspace enough to clear the message and do CTRL-Z to abort.
The relevant "AT command set" manual is no help.
According to TS 127 005 specification, it seems that there's no way to configure the character for SMS sending abortion.
Anyway I can suggest a workaround, based on three different commands:
+CMGW - Write Message To Memory
+CMGD - Delete Message
+CMSS - Send Message From Storage
So basically, instead of using +CMGS that sends the message in one step
Write the SMS to memory with +CMGW (same syntax of +CMGS). After the SMS contents closure with the CTRL-Z character, its answer is
+CMGW: <index>
where <index> is the message location index in the current memory storage
Actually send it with
AT+CMSS=index
Delete the SMS with
AT+CMGD=index
Since memory slots are limited, you will have to delete it anyway. If you realize that the message you are composing during +CMGW phase is wrong, store it anyway with CTRL-Z and skip the actual sending.
As you can see, the entire procedure is performed without using the ESC character (0x1B), can be easily automated and doesn't require much more time to be executed.
Related
In serial communication with devices such as a digital Multimeter (ex. BK Precision 2831E), why do I need to send a query command once but read the output twice? For instance, I sent a query command for the voltage measured, and received an echo but no value of voltage.
I then sent the query command twice which returned the echo and the measured voltage. In essence, to read out the voltage measured, I had to send the same query command in succession twice.
I do not understand this concept. Can anyone kindly help me out with this reasoning.
I have attached a sample code here below:
def readoutmm(portnumber_multimeter):
import serial
import time
ser2 = serial.Serial(
port="com"+str(portnumber_multimeter),
baudrate=9600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE
)
ser2.write(b'fetc?\n') # Query command
voltage= ser2.readline() # Returns echo
voltage=ser2.readline() # Returns measured voltage
voltage=float(voltage)
ser2.close()
packet=[voltage]
return packet
This is actually quite common with devices based on RS232/RS485 protocols.
From the manual of the machine you mentioned, I quote:
The character received by the multimeter will be sent back to the controller again. The controller will
not send the next character until the last returned character is received correctly from the meter. If
the controller fails to receive the character sent back from the meter, the possible reasons are listed
as follows:
The serial interface is not connected correctly.
Check if the same baud rate is selected for both the meter and the controller.
When the meter is busy with executing a bus command, it will not accept any character from
the serial interface at the same time. So the character sent by controller will be ignored.
In order
to make sure the whole command is sent and received correctly, the character without a return character should be sent again by the controller.
On a lot of devices this is actually a setting which you can turn on and off.
Now, as for your question:
why do I need to send a query command once but read the output twice?
You are supposed to read every character back before sending a new one to validate if the character was received correctly. But in your code are actually sending all the character before reading a single one of them.
In scenario's where you have a reliable connection, you method will work as well, but as a consequence you'll need to read twice; once to validate if the command was received and the second time to retrieve the actual data.
Do keep in mind that read buffers might be limited to a certain amount. If you are experiencing unexpected behavior while querying large amount of data and sending a lot of commands, it might be due to the fact these buffers are full.
I understand that MPI_Bsend will save the sender's buffer in local buffer managed by MPI library, hence it's safe to reuse the sender's buffer for other purposes.
What I do not understand is how MPI_Ssend guarantee this?
Send in synchronous mode.
A send that uses the synchronous mode can be started whether or not a matching receive was posted. However, the send will complete successfully only if a matching receive is posted, and the receive operation has started to receive the message sent by the synchronous send. Thus, the completion of a synchronous send not only indicates that the send buffer can be reused, but also indicates that the receiver has reached a certain point in its execution, namely that it has started executing the matching receive
As per above, MPI_Ssend will return (ie allow further program execution) if matching receive has been posted and it has started to receive the message sent by the synchronous send. Consider the following case:
I send a huge data array of int say data[1 million] via MPI_Ssend. Another process starts receiving it (but might not have done so completely), which allows MPI_Ssend to return and execute the next program statement. The next statement makes changes to the buffer at very end data[1 million] = \*new value*\. Then the MPI_Ssend finally reaches the buffer end and sends this new value which was not what I wanted.
What am I missing in this picture?
TIA
MPI_Ssend() is both blocking and synchronous.
From the MPI 3.1 standard (chapter 3.4, page 37)
Thus, the completion of a synchronous send not only indicates
that the send buffer can be reused, but it also indicates that the
receiver has reached a certain point in its execution, namely that it
has started executing the matching receive.
Given two applications, A and B, B needs to get value from A in a synchronous way.
In other words, taking the object model for inspiration, application B wants to do some kind of myVar = A.getValue() and continue its execution using myVar in the rest of the code.
I have the handle of application A's main form and i know how to send message to it with SendMessage(). This function waits for the message to be proceed and then return an integer that is the result of the execution. But i don't know how to use this mechanism so that B gets back some complex data structure (string or data record).
It seems to me that using the SendMessage return value is not a good idea for many reasons, so is there a way to do that?
It has to be done through Windows Messages (i already know how to do it through pipes and sockets).
Thank you!
PS: i work with Delphi but that has no importance here, unless you are able to give examples in Delphi to illustrate your answer :)
The return value of a message is an LRESULT, that is a pointer sized value. If what you wish to return fits in such a value, that would be the clean way to proceed. Otherwise you need something else.
You say that you must use Windows messages, and that you are sending these messages between different processes. Given those constraints, there is exactly one solution, namely WM_COPYDATA. That is the only Windows message which can marshal custom data across a process boundary.
So the procedure is as follows:
Send a message from process B to process A. Include in that message a window handle from process B.
When process A receives the message, it must send a WM_COPYDATA to the window handle that was sent in stage 1.
Process B can then receive and process the message sent in stage 2.
Note that the WM_COPYDATA message is sent from process A to process B whilst process A is handling the original message. This means that the WM_COPYDATA is received and processed by process B, before the original message from B to A returns. This can be somewhat confusing, but you did state that you wanted to do this entirely with Windows messages.
This can be done by one of your processes performing VirtualAllocEx() to allocate memory in another process and then use Read/WriteProcessMemory to copy data there.
I have a WH_GETMESSAGE hook that catches WM_KEYDOWN and WM_INPUT (right now only WM_KEYDOWN), what i need is a way to measure time intervals between WM_KEYDOWNs to see how fast user typing. Exactly i need to drop entire keystroke if it was inputed too fast (i.e. input wasn't actually from user, but from some HID keyboard device, like barcode scanner). What i need to do is for each symbol i'm gonna wait for 30 ms and then if none further symbols applied i need to send it to window it was meant for. And that check need to be performed on each WM_KEYDOWN. If new symbol applied i will push it to my queue along with any further symbols that will go within 30 ms limit between messages (actually i tested on my computer it takes something like 31-32 ms to input symbol and barcode scanner needs something like 15-16 ms which will be sufficent).
I figured out following algorithm:
1. If incoming message is WM_KEYDOWN - store it (with time offcourse).
2. If next incoming message isn't WM_KEYDOWN or time-limit exceeded - send stored message to it's recipient and store current message if it's WM_KEYDOWN - go to step 1.
3. If next message came in 30 ms limit - store it too.
4. If next message is VK_RETURN or sequence is longer than 128 symbols - drop current sequence and store it as barcode. Goto step 1.
Current flaw in this algorithm is that sendMessage thing. I used both sendMessage and postMessage but they both just resend it to my hook procedure (which is obvious i guess). Is there any way to just send this message directly to window it was mento to be send?
Or maybe there are other solution for my problem?
My explanation may seem ambiguous so i just write what i need to achieve:
I need to intercept barcode scanner input before it actually reaches window procedure, so no WM_KEYDOWN messages from scanner will reach target window. A barcode message are typically comes with 15-16ms interval between single WM_KEYDOWNs and ends with VK_RETURN.
Also i need to use exactly WH_GETMESSAGE (or similiar hook that will allow me to catch both WM_INPUT and WM_KEYDOWN). WM_INPUT is needed to distinguish input from various devices (basically i'm going to enum all HID keyboards, determine which of them send barcodes if such event occurs i will flag device as barcode scanner and store it's VID&PID to local database and it will be use for other).
Simple task: Send a windows message with dynamically allocated data, e.g. an arbitrary length string. How would you manage the responsibility to free this data?
The receiver(s) of the windows message could be responsible to free this data. But: How can you guarantee that all messages will actually be received and thus the linked data will be freed? Imagine the situation that the receiver is shutting down, so it won't process it's message queue any more. However, the message queue still exists (for some time) and can still accept messages, which won't be processed any more.
Thanks!
PostMessage returns a BOOL that tells you whether the message was posted or not. This is usually good enough, because your window should be valid until it receives the WM_DESTROY and the WM_NCDESTROY messages. After a call to DestroyWindow (which sends these messages) you should not be able to successfully call PostMessage again.
Now, if your PostMessage returns FALSE you have to clean up. If it doesn't, the window procedure has to clean up. Don't send messages that have to be cleaned up to random windows that might not handle them. Actually, don't send any WM_USER + x messages to any windows you don't handle.
There's nothing to do here. As soon as the call to SendMessage returns, you can free the data. As it happens, the other app isn't looking at your memory anyway since it's in a different process. Instead Windows marshals the data across the process boundary.
What's more, if you are receiving the data in a WndProc, you can't take a copy of the pointer to the string. Instead you must take a copy of the contents of the string since that pointer is only valid for the duration of that call to WndProc.
The other point to make is that you have a confusion about the message queue. When you send a message, that happens synchronously and the queue is not involved. The message queue is where posted messages are placed. They are process asynchronously.