Closed fabbbio986 closed 5 years ago
I'm using laserGRBL with my 3D printed laser engraver through USB connection but now I am trying to use it through ESP8266. At the moment I'm trying to use a NodeMCU board (ESP8266 12-e) connected to the arduino UNO that has a CNCshield on it.
I have to highlight first a problem that I have during the sketch websocketserver.ino uploading: when the arduino IDE is compiling the sketch, it gives me an error on line 145. The only way that I have found to upload the sketch is to change from "const char" to "const unsigned char" . Is that normal? Do anyone else has experienced the same problem?
There are not many LaserGRBL users who use WiFi, I do not know who will answer. It is passed a lot of time since the last time I wrote the guide and I have compiled the lib, maybe there was some changes in WifiManager or arduinoWebSockets latest version.
As I said previously with this little modification I have uploaded the sketch and I successfully connected the nodeMCU board to my wifi network using the web interface. After that I have assigned a static address to the nodeMCU (192.168.1.7) through the router settings. Once opened laserGRBL, I switched to LaserWeb8266 mode and put in the field Socket URL the address: ws://192.168.1.7:81 and clicked on the connect button.
At this moment the program gives me the message (on the left window) Connected but the status on the lower right angle is Connecting and after about 10 seconds the status changes to Disconnected.
When the connection is opened LaserGRBL goes in connecting state and a timer is started.
SetStatus(MacStatus.Connecting);
connectStart = Tools.HiResTimer.TotalMilliseconds;
Now if LaserGRBL receive any status report from grbl that report the machine state (Idle, Run, Hold, Door...) the status shown in statusbar lower-right reflect the status received, but if it does not receive a status that change from Connecting to something else in less then 10 seconds, a timeout expire and the connection will be closed.
if (MachineStatus == MacStatus.Connecting && Tools.HiResTimer.TotalMilliseconds - connectStart > 10000)
OnConnectTimeout();
Imho your system is not correctly bridging the serial connection from the arduino to the pc
Does laserGRBL need a confirmation message (from esp8266 + arduino) during the connection process to establish the connection?
Yes, it needs communicate
Is that can be caused by a bad connection between nodeMCU and arduino?
Yes
Should LaserGRBL connect to nodeMCU even if nothing is connected to the RX and TX pins?
No, connect then disconnect because of timeout.
See your ? - Session log
I have checked the session log as suggested and everytime there is a connection timeout error. I have done some other trials and errors with no results and so I have tried to read trough the arduino IDE serial monitor both nodeMCU and Arduino UNO when I press the connection button on laserGRBL. Here it is what I get for the serial monitor of the nodeMCU:
And this is the messages of the Arduino UNO serial monitor:
I don't know if this could help but it seems that the devices can communicate each other. Do you have any other suggestion that I could try? Thank you so much for your help!
Have a good day!
Ciao Fabio Can you run LaserGRBL from command prompt or by a shortcut? If you start LaserGRBL with "comlog" argument "C:\Program Files (x86)\LaserGRBL\LaserGRBL.exe comlog" the program will record a file called "comlog.txt" located in "C:\Users\YourName\AppData\Roaming\LaserGRBL".
In comlog file you can find all the serial data transmitted/received from LaserGRBL. Here is how a valid comlog look like: comlog.txt
Ciao Fabio I just have tried to use the nodemcu lolin chip without success, the problem is on the serial circuit. The solution used for the error on line 145 is this : // Serial.write((const char ) (payload), (lenght)); errore in fase di compilazione sostituito con Serial.write((const PROGMEM uint8_t ) (payload), (lenght)); the wifi connection is ok with esp8266-01,esp8266-pro or best is esp8266 WEMOS D1 Mini, now i use this module with wifi lcd and sd card to work standalone you can see my video at this link https://www.youtube.com/watch?v=fBsigGqBQKA&t=22s Bye
Ciao Fabio Can you run LaserGRBL from command prompt or by a shortcut? If you start LaserGRBL with "comlog" argument "C:\Program Files (x86)\LaserGRBL\LaserGRBL.exe comlog" the program will record a file called "comlog.txt" located in "C:\Users\YourName\AppData\Roaming\LaserGRBL".
In comlog file you can find all the serial data transmitted/received from LaserGRBL. Here is how a valid comlog look like: comlog.txt
Ciao arkypita, I have tried to run LaserGRBL with command prompt but I get the comlog.txt file only if I connect arduino to my PC using the USB cable. If I try to run LaserGRBL with WIFI connection to the ESP8266 + arduino I don't get any file in my folder. During these trials I have noticed 2 things:
I have double checked the electrical connection between the devices but I can't see any error.
Ciao Fabio I just have tried to use the nodemcu lolin chip without success, the problem is on the serial circuit. The solution used for the error on line 145 is this : // Serial.write((const char ) (payload), (lenght)); errore in fase di compilazione sostituito con Serial.write((const PROGMEM uint8_t ) (payload), (lenght)); the wifi connection is ok with esp8266-01,esp8266-pro or best is esp8266 WEMOS D1 Mini, now i use this module with wifi lcd and sd card to work standalone you can see my video at this link https://www.youtube.com/watch?v=fBsigGqBQKA&t=22s Bye
Ciao Pinuxx Thank you for sharing your experience! First of all I have replaced the line and uploaded the sketch but the result is the same. After I have tried to upload the code on a D1 Mini but I have the same results that I have with the nodeMCU. Do you use any level shifter between RX/TX pins or do you use a simple voltage divider between Arduino TX pin ----> D1 Mini RX pin ?
Sorry, you are right. I have implemented comlog.txt for serial debug only.
You can download v3.0.5 https://github.com/arkypita/LaserGRBL/releases/download/v3.0.5/install.exe where I have added full tx-rx logging both for telnet and websocket. Could be activated using comlog switch (as previous).
I suggest to use telnet version instead of websocket. Is more "low level" and easy to debug-diagnose.
I am actually using an arduino board with integrated ESP8266 and it work perfectly. Previously I was using spare ESP8266 and it works too. I think it was your hardware problem.
Do you use any level shifter between RX/TX pins or do you use a simple voltage divider between Arduino
Voltage divider as in schematic should work: https://github.com/arkypita/ESP8266-SerialTelnet
I suggest to put a big electrolytic capacitor near ESP8266 powerline. When esp goes transmitting it drain a lot of current and can reset itself if voltage fall. https://internetofhomethings.com/homethings/?p=396
If I connect the PC through USB to the arduino and I leave the ESP8266 attached to the TX/RX and ground pins of the arduino, I have noticed that the USB connection doesn't work.
WiFi and USB cannot work together.
@fabbbio986 Ciao Fabio , on the attached pic there is my definitive circuit, i'm using the level converter for the tx and rx line to nano and scl and sda I2c line to LCD2004. The voltage divider circuit is ok for esp-01, i don't have tried on wemos and esp8266-pro solution. Pay attention on the power supply line use many capacitor 100nf near to module line feed. and use a good power supply.
Ciao Arkypita, I have found an esp01 module that was laying around and i have decided that it was worth giving it a try. If I use the same code with this module and the connection works! I can use the jog commands with no issues. I cannot explain me why I have all those problems with others esp devices.
Unfortunately I have another problem now. I have tried to send an image from LaserGRBL to the CNC but i get a lot of errors like these:
And if I observe the behaviour of the movements there are some other problems:
I have changed the streaming mode from buffered to synchronous and the threading mode from ultrafast to fast and the errors disappeared but other problems persist.
EDIT: Here there is my socketlog.txt of a session where I have these errors.
@fabbbio986 Ciao Fabio , on the attached pic there is my definitive circuit, i'm using the level converter for the tx and rx line to nano and scl and sda I2c line to LCD2004. The voltage divider circuit is ok for esp-01, i don't have tried on wemos and esp8266-pro solution. Pay attention on the power supply line use many capacitor 100nf near to module line feed. and use a good power supply.
Ciao Pinuxx, Thank you for the photo of your circuit. I'm start thinking that the problems appear when the following kind of ESP8266 (12-e if i remeber well) is used: I have both NodeMCU and D1 mini (not the original one) that have this kind of ESP8266 on it and nothing works. After uploading the code on an ESP-01 module (like the module used on the tutorial written by arkypita) the connection works. Unfortunately now I have other issues (written in the previous post).
Hi fabbio. The instability of the circuit is a signal that you probably have problems with the power supply, use a good power supply with at least 2A and put both leveling(10-100mF) and filtering capacitors(100nF) near pin Vcc to Gnd.
continue from the previous one.. take wire lenght very short.
Unfortunately I have another problem now. I have tried to send an image from LaserGRBL to the CNC but i get a lot of errors like these:
The errors shown in your image are clear telling that sometime LaserGRBL send a valid command but grbl receive it damaged. Usually this is due to electrical disturbances on the serial side.
Ciao arkypita e pinuxx! After changing the power supply everything works like a charm! Thank you. In the meanwhile I ordered an arduino UNO clone with an integrated ESP8266 as suggested and this board works too! At this point I think that the problem that I had is related to the esp8266 12-e version based. Now I have a D1 mini that I would use to create a wireless pendant that sends commands to GRBL. Do you think is it possible? I have uploaded a websocketclient example on the D1 mini and, after setting the wifi data and the server IP, I receive all the status messages from GRBL unit (I can see it on the serial monitor). Now I can't find the way to send a command from D1 mini to the GRBL unit. Could you help me?
Should be simple as sending a string with your gcode followed by \n
webSocketClient.sendData("G0 X10 Y10\n");
and then wait for "ok" or "error" response before send next command
Should be simple as sending a string with your gcode followed by \n
webSocketClient.sendData("G0 X10 Y10\n");
Thank you! I was missing the "\n"!
(I have to use the webSocket.sendTXT("G0 X10 Y10\n"); command instead of webSocketClient.sendData("G0 X10 Y10\n"); otherwise the IDE gives me an error).
and then wait for "ok" or "error" response before send next command
I have written a few line to read the incoming text from the server and compare with a string ("ok") as suggested here but when compiling it gives me an error about the crosses initialization.
WebSocketClient:45: error: crosses initialization of 'String payload_str'
String payload_str = String((char*) payload);
.
The idea is to check the incoming message from the server and if the message is "ok" it gives me the capability to send another command from the client.
ok, I'm here with an update! The previous error was simply a coding error that I have solved!
Now I'm having a little problem with the text received from the GRBL unit.
I try to explain my setup: At the moment I'm trying to connect 3 devices: 1) Laser device with Arduino UNO with GRBL and built in esp8266 module; 2) Pc running LaserGRBL; 3) Wemos D1 Mini with a modified websocketclient sketch example on it.
On the Wemos D1 Mini I have modified the header WebSockets.h (see WEBSOCKETS_NETWORK_TYPE define) like suggested here: https://github.com/Links2004/arduinoWebSockets/issues/119 to have a sort of interrupt function for the messages incoming from Arduino UNO + esp8266. I have made this change because I see that LaserGRBL constantly ask the status to GRBL and so I thought that in this way no information would be lost by the wemos D1 mini when is performing action in his loop.
On the wemos D1 mini I have used an if function, when a TXT is received, to compare 2 strings and check the GRBL message:
` case WStype_TEXT: USE_SERIAL.printf("[WSc] get text: %s\n", payload);
if (strcmp(ok, (const char *)payload) == 0){
buff = 0;
}`
Where ok is defined as: const char ok[] = "ok\r\n" And "buff" is a boolean that tells me if i received or not an "ok" message from GRBL and so allow me to send another movement with the button.
If I connect only the wemos and Arduino each other everything works, but I have a problem when I try to connect LaserGRBL at the same time. LaserGRBL works perfectly but the button on the wemos works only 2-3 times and then stops (to make it work again I have to reset the wemos or perform an action on LaserGRBL). This is caused by the fact that the if statement is not true anymore and it is confirmed by 2 facts:
[WSc] get text: <Run|MPos:63.000,63.000,0.000|FS:0,0|Ov:100,100,100> ok
` if (strstr(((const char *)payload), "ok") != 0) {
buff = 0;
}
` everything works (with LaserGRBL connected too).
Do you have any explanation about it?
Thank you!
const char ok[] = "ok\r\n"
Maybe const char ok[] = "ok\n"
is more correct?
However I am not sure to have understand the whole meaning of the project. Can you explain to me (in italian too, could be easier).
const char ok[] = "ok\r\n"
Maybe
const char ok[] = "ok\n"
is more correct?
No, I have tried with "ok\n" but the strcmp function gives me 3 as output value. With "ok\r\n" the strcmp function gives me 0 and verifies the if statement.
However I am not sure to have understand the whole meaning of the project. Can you explain to me (in italian too, could be easier).
Yes of course! Since I have a wemos D1 mini laying around I'm trying to make a wireless pendant (Joystick to JOG + some other function buttons). At this stage I have:
The idea is to send a JOG command from the wireless pendant to the laser to move the laser head freely and so I'm following these instructions: https://github.com/gnea/grbl/wiki/Grbl-v1.1-Jogging In short I have to send a $J=91XxYyFzzzz command and then wait for an "ok" response from GRBL before sending a new command. With no LaserGRBL connected I have no problem in using the strcmp command to check the messages and move the laser by pushing the button on the pendant. The issue I have is that when I connect LaserGRBL, the pendant stops working after 2-3 movements.
By checking on the serial monitor what I receive on the pendant and comparing it to the comlog file generated by laserGRBL, all the data received are identical (so I have no messages lost by the pendant), except for some messages when I press the pendant button: On the serial monitor sometimes the "ok" response is in the same string of the status (requested by LaserGRBL constantly) like this one:
[WSc] get text: ok <Jog|MPos:605.350,526.500,0.000|FS:6000,0>
I have bypassed this problem using the strstr function instead of the strcmp but I can't understand why I have both messages in the same string (I think a sync issue).
I take the opportunity to ask you another question: After releasing the button on the pendant I want to send a 0x85 command wich is a jog cancel real-time command to have a low-latency feel.
The 0x85 command is describe as:
0x85 : Jog Cancel Immediately cancels the current jog state by a feed hold and automatically flushing any remaining jog commands in the buffer. Command is ignored, if not in a JOG state or if jog cancel is already invoked and in-process. Grbl will return to the IDLE state or the DOOR state, if the safety door was detected as ajar during the cancel.
Do you know how can I send this kind of messages trough websocket?
Versione Italiana:
Sì, certamente! Siccome ho una wemos D1 mini inutilizzata sto provando a realizzare un pendant wireless (Joystick per JOG + altri pulsanti). In questa fase ho:
L'idea è di inviare un comando JOG dal Pendant wireless al laser per spostarlo liberamente e quindi sto seguendo queste istruzioni: https://github.com/gnea/grbl/wiki/Grbl-v1.1-Jogging In breve devo inviare un comando $ J = 91XxYyFzzzz e quindi attendere una risposta "ok" da GRBL prima di inviare un'altro comando. Senza LaserGRBL collegato non ho problemi nell'usare la funzione strcmp per fare questa verifica e spostare il laser premendo il pulsante sul pendant. Il problema che riscontro è che quando collego LaserGRBL, il pendant smette di funzionare dopo 2-3 movimenti.
Controllando sul monitor seriale ciò che ricevo sul pendant e confrontandolo con il file comlog generato da laserGRBL, tutti i dati ricevuti sono identici (quindi non ho messaggi persi); la differenza la ho su alcuni messaggi quando premo il pulsante sul pendant: Sul monitor seriale a volte la risposta "ok" è nella stessa stringa dello stato (richiesta da LaserGRBL costantemente) come questa:
[WSc] ottiene il testo: ok <Jog | MPos: 605.350,526.500,0.000 | V: 6000,0>
Ho aggirato questo problema usando la funzione strstr invece di strcmp ma non riesco a capire perché ho entrambi i messaggi nella stessa stringa (penso un problema di sincronizzazione).
Colgo l'occasione per farti un'altra domanda: Dopo aver rilasciato il pulsante sul pendant, vorrei inviare un comando 0x85 che è un comando "jog cancel" in tempo reale per avere una risposta veloce del joystick.
Il comando 0x85 è descritto come:
0x85: Jog Cancel Annulla immediatamente lo stato jog corrente con un feed hold ed esegue automaticamente la pulizia di eventuali comandi jog rimanenti nel buffer. Il comando viene ignorato, se non si è in uno stato JOG o se jog cancel è già stato richiesto. Grbl tornerà allo stato IDLE, oppure DOOR se la porta di sicurezza è stata rilevata come socchiusa durante l'annullamento.
Sapresti come posso inviare questo tipo di messaggi tramite websocket?
Grazie mille!
take the opportunity to ask you another question: After releasing the button on the pendant I want to send a 0x85 command wich is a jog cancel real-time command to have a low-latency feel.
The 0x85 command is describe as: 0x85 : Jog Cancel [...]
Do you know how can I send this kind of messages trough websocket?
0x85 is a real-time command like ~ cycle start/resume, ! feed hold, ^X soft-reset
As all others real time command it should be sent without additional line-feed or carriage-return. Because 0x85 it is not available on the keyboard you should cast the number to a char to use it as sendTXT parameter.
sendTXT((char)0x85)
https://github.com/gnea/grbl/wiki/Grbl-v1.1-Commands#grbl-v11-realtime-commands https://github.com/gnea/grbl/wiki/Grbl-v1.1-Interface#real-time-control-commands
About your main problem I have some doubts about the possibility of having two source of commands at the same time. For example If both sources send a command and grbl reply with one ok and one error, how do you decide to who send the ok and to who send error?
A well-designed socketserver code would need to synchronize the two command flows to a single one and sort the responses to the correct source.
However what you are experiencing look like a sync problem, but I don't know the cause. Sorry I don't know the websocket library very well.
take the opportunity to ask you another question: After releasing the button on the pendant I want to send a 0x85 command wich is a jog cancel real-time command to have a low-latency feel. The 0x85 command is describe as: 0x85 : Jog Cancel [...] Do you know how can I send this kind of messages trough websocket?
0x85 is a real-time command like
~ cycle start/resume, ! feed hold, ^X soft-reset
As all others real time command it should be sent without additional line-feed or carriage-return. Because 0x85 it is not available on the keyboard you should cast the number to a char to use it as sendTXT parameter.
sendTXT((char)0x85)
https://github.com/gnea/grbl/wiki/Grbl-v1.1-Commands#grbl-v11-realtime-commands https://github.com/gnea/grbl/wiki/Grbl-v1.1-Interface#real-time-control-commands
I have tried to send the command
webSocket.sendTXT((char)0x85);
but it gives me an error:
call of overloaded 'sendTXT(char)' is ambiguous
Are you sure that I can cast 0x85 to a char?
The char datatype encodes numbers from -128 to 127; If I'm not wrong 0x85 should be equivalent of 133.
About your main problem I have some doubts about the possibility of having two source of commands at the same time. For example If both sources send a command and grbl reply with one ok and one error, how do you decide to who send the ok and to who send error?
A well-designed socketserver code would need to synchronize the two command flows to a single one and sort the responses to the correct source.
However what you are experiencing look like a sync problem, but I don't know the cause. Sorry I don't know the websocket library very well.
The idea is to use LaserGRBL and the pendant not at the same time. By sending a $J=91XxYyFzzzz command from pendant, GRBL automatically accept a jog command only if Grbl is in either the 'Idle' or 'Jog' states. So If i try to use the joystick while LaserGRBL is running, all the commands from the pendant should be ignored.
Compiler is telling you that a function with name sendTXT with char parameter does not exist or can be confused with another function.
What I have suggested you is conceptually what I am doing in LaserGRBL websocket client. When I need to send an immediate command i call the function Write(byte b) declared as:
public void Write(byte b)
{
if (IsOpen)
{
if (GrblCore.WriteComLog) log("tx", string.Format("[0x{0:X}]", b));
cln.Send(new string((char)b, 1));
}
}
Are you sure that I can cast 0x85 to a char? The char datatype encodes numbers from -128 to 127; If I'm not wrong 0x85 should be equivalent of 133.
Sincerely I don't really know why char is signed in arduino. I was thinking that it was unsigned, but i'm wrong.
I am C# so my send want c# string, and c# char is 16 bit unsinged number that rapresent the unicode value of a char.
Regardless of how it is done you should send a single byte of data, and this byte should be 0x85 (binary 10000101, decimal 133). Maybe you have a sendbyte function? Use that! Don't have sendbyte? Use sendstring and find a way to send a single character with that value!
... Sincerely I don't really know why char is signed in arduino. I was thinking that it was unsigned, but i'm wrong.
I am C# so my send want c# string, and c# char is 16 bit unsinged number that rapresent the unicode value of a char.
I think that it is possible to use unsigned char but i don't know if it is possible to convert it into a string.
Regardless of how it is done you should send a single byte of data, and this byte should be 0x85 (binary 10000101, decimal 133). Maybe you have a sendbyte function? Use that! Don't have sendbyte? Use sendstring and find a way to send a single character with that value!
On the websocketclient.ino example (https://github.com/Links2004/arduinoWebSockets/blob/master/examples/esp8266/WebSocketClient/WebSocketClient.ino) 2 functions are called: webSocket.sendTXT(""); and webSocket.sendBIN(payload, length); (example line 46)
But for the second one I haven't understood how to use it for my needs.
how is going?
At the moment I haven’t found any way to send the 0x85 command. I have asked in the websocket repository too but for the moment nobody has answered. The only thing that I can try is to send the feed hold “!” Command and after that the resume “~” command. This should stop the CNC movements, cancel the jog motion and flush all remaining jog motions in the planner buffer and resumes the feed hold state. I know that sending the 0x85 command it would be preferable but I don’t know how to do that.
@fabbbio986 the sendBIN function signature is the following:
bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false);
bool sendBIN(const uint8_t * payload, size_t length);
I didn't read the whole discussion but based on your previous comment I understood you need to send either binary 10000101, decimal 133 from:
Regardless of how it is done you should send a single byte of data, and this byte should be 0x85 (binary 10000101, decimal 133). Maybe you have a sendbyte function? Use that! Don't have sendbyte? Use sendstring and find a way to send a single character with that value!
So you can use sendBIN to send the decimal number since it accept a __uint8_t__, is it good?
Thank you for your answer! In the meanwhile Links2004 helped me in the websocket repository. He suggested me to try:
uint8_t buf[] = { 0x85 };
webSocket.sendTXT(buf, 1);
And it works perfectly!
Now I'm working on the code and I have received a keypad to add all the buttons I need. I hope to share my results in a short time.
Hi everyone! First of all thank you arkypita for sharing your work! I'm using laserGRBL with my 3D printed laser engraver through USB connection but now I am trying to use it through ESP8266.
At the moment I'm trying to use a NodeMCU board (ESP8266 12-e) connected to the arduino UNO that has a CNCshield on it.
I have to highlight first a problem that I have during the sketch websocketserver.ino uploading: when the arduino IDE is compiling the sketch, it gives me an error on line 145. The only way that I have found to upload the sketch is to change from "const char" to "const unsigned char" . Is that normal? Do anyone else has experienced the same problem?
This is the error message given:
As I said previously with this little modification I have uploaded the sketch and I successfully connected the nodeMCU board to my wifi network using the web interface. After that I have assigned a static address to the nodeMCU (192.168.1.7) through the router settings. Once opened laserGRBL, I switched to LaserWeb8266 mode and put in the field Socket URL the address: ws://192.168.1.7:81 and clicked on the connect button.
At this moment the program gives me the message (on the left window) Connected but the status on the lower right angle is Connecting and after about 10 seconds the status changes to Disconnected.
During these 10 seconds I can't send any "gcode command" but if I send the "WIFIRESET" command it works.
Does laserGRBL need a confirmation message (from esp8266 + arduino) during the connection process to establish the connection? Is that can be caused by a bad connection between nodeMCU and arduino? Should LaserGRBL connect to nodeMCU even if nothing is connected to the RX and TX pins?
Thank you for your help!