Pen Command (M280P0S0) is occuring before move command (G1) completes - g-code

Hello I'm having a problem with the sequence order of events. I am under the impression that g-code (or the machine) will wait for each command to complete before moving on to the next command. But I'm not seeing this.
I have a plotter machine that controls a pen. The machine has an X & Y axis. The Pen Up/Down command is controlled by a code M280P0S30/M280P0S0
The pen is going down too early. I can see 2 possible reasons for this:
Perhaps there's some problem here with my code or understanding of what these codes do
G28 X Y ; Auto-home
G90 ; ABS
G21 ; MM
G1 F3000 ; Speed
M280P0S30 ; Pen up
;;; Problem occurs here: Pen goes down
G1 X50 Y50 ; Move command
M280P0S0 ; Pen down
G4 P50 ; Pause
G1 X50 Y55 ; Move command
G1...snip.... more move commands
Can anyone tell me if there are any mistakes here?
Perhaps the M280 codes do not wait for the G1 codes to complete?
Perhaps the G4 code is throwing things off?
Perhaps I need a faster/slower speed?
I am wondering if the machine buffers and blocks individually based on the type of codes. (A G1 command would block another G1 command but not a M280 command.)
I'm sending the commands over a serial connection. There are too many commands to send all at once so I introduced a pause between the commands. Is it possible that the machine blocks and buffers per-servo?
In pseudo code that looks like:
Wait 1 second
Send g-code command: G28 X Y ; Auto-home
Wait 1 second
Send g-code command:G90 ; ABS
Wait 1 second
Send g-code command:G21 ; MM
Wait 1 second
Send g-code command:G1 F3000 ; Speed
Wait 1 second
Send g-code command:M280P0S30 ; Pen up
Wait 1 second
(Problem occurs here: Pen goes down)
Send g-code command:G1 X50 Y50 ; Move command
Wait 1 second
Send g-code command:M280P0S0 ; Pen down
Wait 1 second
Send g-code command:G4 P50 ; Pause
Wait 1 second
Send g-code command:G1 X50 Y55 ; Move command
Is it possible that the machine will allow an M280 code to run before a G1 code if the machine is currently busy with an existing G1 code?

Related

How to automatically stop a program.c and input a command in Linux?

So i have this program that is supposed to be a (super basic) server in Linux that shows me this menu:
What u want to do?
0 -> Exit
1 -> Add product
2 -> Show products list
3 -> Turn on server
And i want it so that when you put the number 3, the server.c stops, like when you press CTRL + Z and send the commnad "bg" so that the server runs in backgroundg (like when you do the command "./server&") so i can open the client.c and interact with the server.
Example of what i want it to do when you input 3 (on here i did it manually on the propmt):
estgv18708#viriato:~/tp6$ ./server
What u want to do?
0 -> Exit
1 -> Add product
2 -> Show products list
3 -> Turn on server
3
^Z
[1]+ Stopped ./server
estgv18708#viriato:~/tp6$ bg
[1]+ ./servidor &
Thanks in advance! :D
Probably an XY-problem here -- why would you want to do this?
The basic issue is that this presupposes your server program is run from a shell and you want to return to the shell to do stuff. But what is the server going to be doing in the meantime? The shell will have (need) control of the input and output so the server pretty much just needs to wait.
You can get the same effect as ^z by calling kill:
kill(getpid(), SIGSTOP);
will have the server send a STOP signal to itself. The shell (which is monitoring progress of the program), will notice this and print the "Stopped" message and then prompt for what to do. The server will be stopped, and you can resume it with the shell's fg command (or put it into the background with bg). However, if your server program is not run from a shell (it is just running directly in a terminal), this will simply stop the server and nothing else will happen.
More commonly what you want to do here is run a subshell:
system(getenv("SHELL"));
which will start a new shell and will wait for it to complete. When the shell exits (use the exit command or type ^d at the shell prompt) the server will resume.
If you want the server to continue to run while the shell runs, you can use fork+exec to run the shell in the child and continue running the server in the parent, or you can use fork+_exit to run the server as a grandchild and have the parent shell continue, but you need to be careful about using the terminal input and output (the server and shell will be fighting for it).
Cant u just do system("bg"); ?
U dond need to stop the program just need to put it on the background

Can't get RS-232 Commands to work sending from arduino

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.

Script to run multiple OpenCv programs in Windows

I like to run several OpenCV programs one by one in a DO Loop. After searching the web , think for this case need to use batch file. Is that right?
I have 10 OpenCV programs. Each program detect specific features in the image with some successful rate. So, for any image(with many features to be detected) I wonna run first the program with the highest successful rate. If this failed to detect feature then run next one with second highest rate and so on. So, for example program1 is the one with the highest rate, then come program2 and so on
So I have output for each of the 10 OpenCv programs. Let we say output 1 if detect the feature (or the object) in the image and 0 if it failed. So the script should start the program 1 first and if the outcome of this program is 1 then will do something (not important at the moment what), but if the outcome is 0 then need to start the program 2. Same for program 2. If the output of program 2 is 1 then do something (also not important what), but if the output is 0 (means did not detect the object) then run the next program (means program3)
Any idea how it should look like?
I have thinking of something like this , but not sure about the control
#ECHO OFF
START program1.exe
ECHO Timeout waiting for program1.exe to start
GOTO :EOF
:: if the output of program1.exe is 1 then do somethig, else if the output of program1.exe is 0 run the program2.exe (I dont know how this part should be in the script)
:: not sure for control
:startnext
program2.exe
:: or START program2.exe

C sleep variance when ran by cron

I wrote some C code to switch on and off some LEDs.
Actually, I want to trigger them accurate to music but haven't found a better way than using usleep() in between yet.
Anyway, turning on the LEDs, waiting at usleep() and turning off the LEDs again works pretty accurate when I call the program on the command line.
Now I'd like cron to execute the program let's say every five minutes. Therefore I added following cronjob with crontab -e:
*/5 * * * * bash ~/startShow.sh >~/log 2>&1
Same problem without the shell script.
*/5 * * * * ~/projects/startLEDShow >~/log 2>&1
startShow.sh
date
/usr/sbin/i2cset -y 1 0x40 0x00 0x21 # Preparation for communication via I2C
cd projects
./startLEDShow
The program is triggered every five minutes, but at some point (not always the same point) the execution seems to stop for a moment and resumes about a second later. That is only when the program is ran by cron, not when I call it from the commandLine.
Why is that so, is this perhaps due to the usleep() used in the program, and how can I make sure that the program execution isn't suspended for some time?
Update 1: Here is an extract with the usleep-section from the program
// Start reading
while(NULL != (word = readToChar(fp, wordBuffer))) {
// Values for the LEDs are stored in a struct
updateValuesForLEDs(next, word); // Update struct "next"
usleep(((next->time/timeFactor - lastTime)*1000000)); // Wait
lastTime = next->time / timeFactor; // Set lastTime for next iteration
setLEDs(i2cConnection, next, buffer); // Set the LEDs to the brightness values stored in struct "next" via I2C
}
Update 2:
After ensc's comment I found way to solve my issue.
The cronjob was started with a nice value of 10 whereas most other processes' values circled around 0. Setting my job to a lower nice value (which requires root privileges) gives it a higher priority and prevents it from being paused.
00 20 * * * sudo nice -n -20 ~/projects/startLEDShow >~/log.txt 2>&1
I doubt you're running a real-time operating system, so usleep is not guaranteed to wake up your process with any guarantee of performance. For that matter, even if your process is woken up at the right time, it's always possible for the kernel to interrupt it and do somehing else for an arbitrary amount of time.

How do you enter something at a console prompt programmatically?

I have program, that must interact with a console program before my program can continue what it is doing. I'm trying to avoid my user from having to interact with this dos program. So, I created a .bat file that does everything I need to do except for the last step which still requires user interaction that I'm trying to avoid.
Specifically, the command I type ends up at a prompt where I need to automatically enter y and then Enter (to say yes to the prompt) and then I want to exit out.
Is there any way that I can make this happen automatically without my user having to enter y and Enter? Ideally, I'd like to have the console window NOT even pop up while this is going on.
You can pipe in a 'y' character into the program like so:
echo y | executable.exe
Multiple lines can be entered like so:
(echo y
echo n) | executable.exe
...which will pass first 'y' then 'n'.
See tip from Microsoft here.
The post from Microsoft also clearly says :
Do not type a space between the "y" and the pipe symbol (|)
and indeed, I noticed that in my case
echo y | executable.exe
doesn't work
while
echo y| executable.exe
works fine
I used the following, since "echo y | executable.exe" didn't worked for me
// Write a "Y" to the process's input
proc.StandardInput.WriteLine("Y");
// Now that we've sent the confirmation "Y" wait for the process to exit
proc.WaitForExit();
as posted here: https://www.experts-exchange.com/questions/27024185/C-ProcessStart-How-to-automatically-press-the-Y-key.html

Resources