Having issues sending RS-232 Commands from Arduino Mega to ENTTEC DMXStreamer. The RS-232 API is located here enter link description here. I am trying to send 3 commands H1 (Stop Show) HA (Load Show in slot A) H0 (Start Show that is loaded). I have tried multiple things to send the data.
setup(){
Serial2.begin(9600); //default baud rate of DMXStreamer
Serial.begin(115200);
}
loop(){
Serial2.print("H1HAH0");
delay(3000);
}
I also tried
Serial2.write(0x48);
Serial2.write(0x31);
Serial2.write(0x48);
Serial2.write(0x41);
Serial2.write(0x48);
Serial2.write(0x30);
All I get in return from the DMXStreamer is '''. I don't even see those characters as possible response codes in the API. A successful send is supposed to return '!' and negative response is '?'.
This is the code I used to read the response.
String Message = "";
while(Serial2.available())
{
char inChar = Serial2.read();
Message += inChar;
}
Serial.println(Message);
I then hooked up a usb to serial converter to the DMXStreamer and used Realterm to send the data. I went to the send tab in Realterm and typed "H1HAH0" in the box and pressed the Send ASCII button. The Streamer returned positive response !!! and I got the desired result the DMX show in slot A started playing.
What am I doing wrong in sending the data. As a side note I at one point want to use the command H3101 instead of H0. The notes for the command from the API are below. I am not sure how to sent the 101 part of the command based on the notes. Any help would be greatly appreciated.
From the API
H Command
This command is used to start,stop a show and set the show to run.
H0 Command, Start Show Format H0
If no show is stored this will have no effect
H1 Command, Stop Show The command will stop the show.
Format H1
H3 Command, Start Show with loop times
Format H3x
Warning the X value is 8 bit BINARY data, not ascii.
This command will start the show and loop X times.
To run the show once X must be set to 0x00 the maximum number of loops is 100. If X is set to 101
the show will loop forever.
The bytes are commming slow on 9600 baud. You will see available() 0 between them and before they arrive. Use Serial2.readString() for test. It waits for next byte until a second.
String Message = Serial2.readString();
Serial.println(Message);
Note: this is for a test. Don't use String or readString in the final sketch. Use C strings and readBytes with length or terminator specified.
Related
I am working on terminal based text editor and stuck at a point where I need to differentiate whether the input text from read() function is a clipboard paste text or a keyboard text input.
#include <unistd.h>
char read_key_input() {
char ch;
int read_count;
while ((read_count = read(STDIN_FILENO, &ch, 1)) != 1)
{
// Handle error if any
}
return ch;
}
...
Edit: Here's what I ended up doing.
void read_key_input(void (*callback)(int)) {
char* text = malloc(UINT8_MAX);
int read_count;
while ((read_count = read(STDIN_FILENO, text, UINT8_MAX)) == -1)
{
// Handle error if any
}
// Handle escape sequences if found and return early
...
if (read_count > 1) {
// It's probably a clipboard text. So change the editor mode to input and loop through all the characters one by one.
else {
// It's a user keyboard text input
}
// Revert back to the original editor mode if changed
}
I updated the code to retrieve more than one byte at a time (as suggested by #AnttiHaapala) and process each byte. Seems to be sufficient for my text editor's need for now. Will post back if I update.
Usually you can differentiate this by counting the number of characters you've received in rapid succession. So if you get the keypresses more rapidly than say 1000 characters per minute, then it is likely a clipboard paste... or nonsense.
Furthermore, if you've set the terminal to raw mode, then you can easily monitor individual keypresses. Also make read accept more than one byte at once - with read that is the maximum number of bytes to receive without blocking when available anyway.
One example of such an interactive terminal program would be IPython - here two lines typed separately:
In [1]: print("Hello")
Hello
In [2]: print("World")
World
And here pasted in one go:
In [3]: print("Hello")
...: print("World")
...:
Hello
World
Notice how the prompt is different, and the program runs only after there has been a separate Enter key hit after a small delay.
AFAIK, you cannot do what you want (reliably).
The clipboard is related (usually) to some display server, e.g. Xorg or Wayland server (Weston). And X11 might have distant clients (hence, a clipboard operation could be slow, if crossing some ocean).
Some Linux machines (perhaps the web server at Stackoverflow) do not run any display server.
You could code a GUI application, e.g. using GTK or Qt.
You could test if your standard input is a terminal with termios(3) functions or isatty(3) (i.e. with isatty(STDIN_FILENO) or isatty(STDOUT_FILENO) for standard output)
If your program is run inside a crontab(1) job, or a unix pipeline, the standard input won't be a terminal, and there might not even be any display server running.
You could take inspiration from the source code of GNU emacs, which does detect when a display server is available (probably using environ(7), e.g. getenv(3) of "DISPLAY"...)
On Linux you might open(2) /dev/tty (see tty(4)) to access your terminal. In some cases, it does not exist.
Hey #jiten not sure if you checked like
its key input detect and check wether it's input is one by one key
or its instant bulk input.
I have to write a self-refreshing progress bar to the terminal - that denotes how much of a file has been copied so far. I tend to refresh the output every 1000 bytes or so. To refresh the screen, I have used the following outline:
printf("\r"); // clear previous output
// output is the progress bar, percent is an integer (0 to 100)
printf("%s %d file written", output, percent);
It works fine when the terminal is large. However, when the terminal is small, such that the entirety of the progress bar doesn't fit into it, the carriage return doesn't work. It only clears the visual single line, not the entire line. I wrote a sample program to demonstrate:
printf(
"abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"
"abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghi"
"j");
printf("\rCHECK");
As you can see in the below image, since the terminal is small, only some part of the entire print output is deleted.
Putting multiple carriage returns has no effect.
Then, what is a good way to build such a continuously refreshing terminal output in C?
I also tried clear screen (printf("\033[2J");) but it didn't work for me. It tends to insert arbitrary number of whitespaces at the beginning of the output, see image for example:
Generally, the only way to tell if your message has wrapped to the next line of the terminal is to compare it to the terminal width (number of columns). You can get that info by using terminfo(3)
#include <term.h>
int main() {
setupterm(0, 1, 0); /* default terminal setup from the TERM envvar */
Now you can access the global var columns to know how many columns there are on the terminal. You can also use putp(tigetstr("cuu1")); to go up one line on the terminal. So you can keep track of how long your status message is and figure out how far up you need to go to get back to the beginning of it.
I am trying to implement my library to send data over tcp connection.
In official documentation from Quectel they let you select AT+QIMODE=1 also called Transparent mode where all data sent from UART is sent over tcp connection.
I am trying to check connection status before sending data so would want to change to command mode and use AT+QISTAT. I tried sending '+++' to chip but it's sending '+++' to my server, so it's not working. Any help is greatly appreciated.
Link to official documentation, please refer to page 162 section 7.2.21
Have you ensured you have the correct time delay before and after the +++ sequence?
The documentation at section 2.2.11 (page 22) states that there must be a quiet period of 0.5 seconds before and after the +++ for it to be recognised.
To prevent the "+++" escape sequence from being misinterpreted as data, it should comply to following sequence:
No characters entered for T1 time (0.5 seconds).
"+++" characters entered with no characters in between. For CSD call or PPP online mode, the interval between two "+" MUST be less than 1 second and for a transparent TCPIP connection, the interval MUST be less than 20 ms.
No characters entered for T1 time (0.5 seconds).
Switch to command mode, otherwise go to step 1.
If you still don't have any success please post some example code.
I'm completely new to gnuplot and have only learned the basics to start plotting. I'm writing a C program that does DSP and needs to plot the result in real time. In addition, I've setup my program in such following manner to incorporate the plot '-' feature from gnuplot. The parent process will perform the DSP computation constantly, and sends the result to the child using pipe in real time. The child will receive a signal from parent, wake up, and sends the result to gnuplot via pipe.
Basically, the path of data goes as such:
Parent(Computation) -> Pipe -> Child (Wait on Input from parent) -> Pipe -> gnuplot (Plotting)
For example, in the child, enclosed in a conditional wait
getline(&lineBuffer, lineSize, stdin);
printf("%s", lineBuffer);
fflush(stdout);
where lineBuffer can be any arbitrary char*, will redirect data from parent to gnuplot. I have all the necessary data for plotting, and it can be formatted in any format. However, after trying the following, there has been no success.
If not yet defined appearances and label,
set terminal x11 persist noraise
set xlabel "Frequency"
set ylabel "Decibel"
set xrange [0:2000]
set yrange [-100:100]
set style data lines
Start initial plot command,
plot '-' using 1:2 smooth unique
Start sending data, each point is a new line, where I formatted my data to be
Frequency Decibel
at a particular time, for example
1000 -30.00
1001 -31.00
....
End data by sending
e\n
Then I restart the process sending the data, and end it with
replot
Does this seem right? On the other hand, I'm also interested in plotting the time series of a particular frequency, and after numerous searches, apparently I need a buffer or a temporary file to accomplish this, is that correct also?
How to be sure what is end of an AT command send to GSM module?
I need some character or string that represent end of AT command for every case due to finding when whole response is received.
I guess it have something with "\r\n" sequence but, this sequence could be at the beginning of AT command response?
Like you suppose it's \r\n.
This defines the end of a line.
And it makes only sense to process complete lines.
Some commands respons with only OK\r\n, some with some data.
So you should build at first a parser, who can detect complete lines, so they can be
processed with a function that handles responses.
Sometimes you can get even responses you don't request, like change events net login or the sim status #QSS: 2\r\n.
So you need to know what answer you expect and wait until you get this
Here is what I used in Python. It works. There might be some other better solutions.
ser = serial.Serial(com, baudrate, timeout=5)
while True:
# a simple AT return result parser
new_char = ser.read(1)
byte_flow += new_char
if len(byte_flow) >=4 and byte_flow[-4:] == b'\r\nOK':
break
elif len(byte_flow) >= 7 and byte_flow[-7:] == b'\r\nERROR':
break
byte_flow += ser.read(2) # the final '\r\n'
You can add more elif if there is any other patterns.
Depending on mode and command
I.e.
<CR> or <CR><LF>
http://www.3gpp.org/ftp/Specs/html-info/27007.htm
Referring the original Hayes command set Wikipedia is stating:
<CR> Carriage return character, is the command line and result code
terminator character, which value, in decimal ASCII between 0 and 255,
is specified within parameter S3. The default value is 13.
So it should be possible to set any character to indicate the end of the response (and as well the end of any command sent to the modem a well).
Anyhow <CR>s are not only returned as last character by many modem's responses.
So it might be an interesting experiment whether writing a different character value to S3 would just change the last character sent at the end of the modem's response, or if this would change any <CR> sent during the modem's response to be the value stored in S3.
The response format is command specific. While there are certain similarities ("OK\r\n"), in the end you need explicit handling for each.