Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatibility with G2Core #812

Closed
3 of 9 tasks
simonemarin opened this issue Feb 16, 2023 · 17 comments · Fixed by #813
Closed
3 of 9 tasks

Incompatibility with G2Core #812

simonemarin opened this issue Feb 16, 2023 · 17 comments · Fixed by #813

Comments

@simonemarin
Copy link

Description

CNCJS does not complete the initial setup with G2Core. Some extra info here: synthetos/g2#514
This is what is answering:
CNCjs 1.10.1 [TinyG]
Connected to COM32 with a baud rate of 115200

feeder> {ej:1}
feeder> {jv:4}
feeder> {qv:1}
feeder> {sv:1}
feeder> {si:100}
feeder> {spe:n}
feeder> {spd:n}
feeder> {spc:n}
feeder> {sps:n}
feeder> {com:n}
feeder> {cof:n}
feeder> {sr:{stat:t,line:t,vel:t,feed:t,unit:t,coor:t,momo:t,plan:t,path:t,dist:t,frmo:t,tool:t,posx:t,posy:t,posz:t,posa:t,posb:t,posc:t,mpox:t,mpoy:t,mpoz:t,mpoa:t,mpob:t,mpoc:t,spe:t,spd:t,spc:t,sps:t,com:t,cof:t}}
feeder> {sys:n}
feeder> {mt:n}
feeder> {pwr:n}
feeder> {qr:n}
feeder> {sr:n}

Versions

  • CNCjs: 1.10.1 (Windows)

How Do You Install CNCjs?

  • [x]Download the CNCjs Desktop Application

CNC Controller

  • [] Grbl
  • Smoothieware
  • TinyG/g2core

Hardware

  • Raspberry Pi
  • Desktop or Laptop
  • Mobile Device

Operating System

  • Not Applicable
  • Windows
  • Mac
  • Linux
@ril3y
Copy link

ril3y commented Feb 17, 2023

@cheton I would not say that "incompatible" is the right word. As you can see from the link there is clearly something going on at initial connect for cncjs. If you connect to ANY other terminal to the serial port g2 sends status message on connect. However it looks like cncjs is not getting this. If you connect to another terminal FIRST then disconnect and connect to cncjs it works just fine.

If you dont have a g2core setup Cheton I can send you one for testing. I can't remember if we sent you a board.

@cheton
Copy link
Collaborator

cheton commented Feb 17, 2023

@ril3y I have an Arduino Due board that could be used for verification. Would you recommend that I try using the firmware image provided in this link?

https://drive.google.com/file/d/1SAU-vpRx9YbPC1ikLeY-4K2qexnzPPKU/view?usp=sharing

@ril3y
Copy link

ril3y commented Feb 17, 2023 via email

@simonemarin
Copy link
Author

Hallo and thanks for the great support, I'll be off for a week but be assured I ll post the results and any tests you need me to do starting from the 26th of feb.

@ril3y
Copy link

ril3y commented Feb 17, 2023 via email

@cheton
Copy link
Collaborator

cheton commented Feb 18, 2023

Although I have managed to replicate this issue on some devices or environments intermittently, I am still unable to determine the cause of not receiving response from the serialport module when connecting to an Arduino Due. Additional investigation is required.

@cheton
Copy link
Collaborator

cheton commented Feb 18, 2023

After several attempts, including resetting the Arduino Due and reconnecting the USB cable, I was able to get it working using the macOS app. However, I have not had any success with the Windows app.

macOS app
image

Windows app
image

Note that the Serial Monitor in the Arduino IDE does not have this issue.

@cheton
Copy link
Collaborator

cheton commented Feb 18, 2023

Here is a simple program that I am currently using to test the connection.

index.js

const { SerialPort } = require('serialport');
const { ReadlineParser } = require('@serialport/parser-readline');

const port = new SerialPort({
  path: '/dev/cu.usbmodem143301', // replace with your serial port device path
  baudRate: 115200,
});
const parser = port.pipe(new ReadlineParser({ delimiter: '\n' }));

port.on('open', () => {
  console.log('Serial port opened');
});

parser.on('data', (data) => {
  console.log(`Received data: ${data}`);
});

const readline = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});

readline.on('line', (line) => {
  port.write(`${line}\n`);
});

readline.on('close', () => {
  console.log('Closing serial port');
  port.close();
});

package.json

{
  "dependencies": {
    "@serialport/parser-readline": "^10.5.0",
    "serialport": "^10.5.0"
  }
}

@MitchBradley
Copy link
Contributor

I just remembered something about Arduino Due. It has two USB ports that can serve as serial connections. The first is intended for firmware download and its USB-Serial function is implemented with a separate ATMEGA 16U2 chip. The second is directly connected to the ATSAM3X8 ARM chip, using the USB hardware inside the ARM. The first USB port is available immediately after power up, but the second one is only available after the firmware running on the ARM has had time to configure the USB engine to be a serial port. There are some pushbuttons that let you choose between download mode and run mode.

The Arduino Due board that I have tends to power up in download mode instead of run mode. In order to make CNCjs (which I ran on a Raspberry Pi Zero W on that machine) connect reliably to the Arduino Due that ran G2core, I had to add an external reset line - a Pi GPIO connected to the Due reset input. After the system powered up, I had a shell script that pulses the Due reset line, before starting CNCjs. That was usually successful in kicking the Due into run mode.

@cheton
Copy link
Collaborator

cheton commented Feb 19, 2023

@MitchBradley
Thank you for the valuable information you provided. It was extremely helpful and saved my day. I had previously sent a question to ChatGPT asking for guidance on how to send a reset signal, and the answer is exactly what I needed.

image

Thanks to your input, I was able to successfully reset the signal, and everything is now working perfectly.

$ node index.js
Serial port opened
{"r":{"fv":0.99,"fb":101.03,"fbs":"101.03","fbc":"settings_othermill_test.h","hp":"g2v9","hv":"k","id":"0084-7bd6-29c6-7bd","msg":"SYSTEM READY"},"f":[1,0,1]}
help
### g2core CONFIGURATION Help ###
These commands are active for configuration:
  $sys Show system (general) settings
  $1   Show motor 1 settings (or whatever motor you want 1,2,3,4)
  $x   Show X axis settings (or whatever axis you want x,y,z,a,b,c)
  $m   Show all motor settings
  $q   Show all axis settings
  $o   Show all offset settings
  $$   Show all settings
  $h   Show this help screen
Each $ command above also displays the token for each setting in [ ] brackets
To view settings enter a token:
  $<token>
For example $yfr to display the Y max feed rate
To update settings enter token equals value:
  $<token>=<value>
For example $yfr=800 to set the Y max feed rate to 800 mm/minute
For configuration details see: https://github.com/synthetos/g2/wiki/g2-Configuration
Note: g2core generates automatic status reports by default
This can be disabled by entering $sv=0
See the wiki below for more details.
For detailed g2core info see: https://github.com/synthetos/g2/wiki
For the latest firmware see: https://github.com/synthetos/g2
Please log any issues at https://github.com/synthetos/g2/issues
Have fun
{"r":{"help":null},"f":[1,0,5]}

The updated script that I used:

const { SerialPort } = require('serialport');
const { ReadlineParser } = require('@serialport/parser-readline');

const port = new SerialPort({
  path: 'COM3',
  baudRate: 115200,
});

const parser = port.pipe(new ReadlineParser({ delimiter: '\n' }));

const delay = ms => new Promise(resolve => setTimeout(resolve, delay));

port.on('open', async (err) => {
  if (err) {
    console.error('Something went wrong:', err);
  } else {
    console.log('Serial port opened');
  }

  try {
    await port.set({ dtr: false });
    await delay(100);
    await port.set({ dtr: true });
  } catch(err) {
    console.error('Error:', err.message);
  }
});

parser.on('data', (data) => {
  console.log(data);
});

const readline = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});

readline.on('line', (line) => {
  port.write(`${line}\n`);
});

readline.on('close', () => {
  console.log('Closing serial port');
  port.close();
});

@ril3y
Copy link

ril3y commented Feb 19, 2023

Great work @cheton thanks for the merge. I will pull it and test it out when its completed.

@giseburt
Copy link

So the DTR line is supposed to be handled by the OS, but Windows doesn’t properly. In our code we use RTS to tell if the is is “listening” (meaning a program opened the port).

TL;DR: I suggest using the node serialport hupcl connection option instead of driving DTR directly.

Windows doesn’t properly drive DTR (set on connect, clear on disconnect) like other OSes do, but it does honor it internally and confusingly, meaning that if DTR isn’t set, RTS isn’t transmitted. See bug here.

Merely set DTR on connection and it’ll work, but you shouldn’t have to do it manually. It appears that that’s what the Serialport-Bindings hupcl does on Windows. See code and mildly unclear docs. If you look up DTR_CONTROL_ENABLE you get here for clearer docs:

Enables the DTR line when the device is opened and leaves it on.

On the other OSs hupcl is the actual setting passed to the OS, and does as it says in their docs: clear DTR when disconnecting, which is also something you want.

@MitchBradley
Copy link
Contributor

clear DTR when disconnecting, which is also something you want.

Well, maybe. It depends on whether you want to reset the controller when the UI disconnects - which could be in the middle of a job.. If the UI is "sending" in the conventional grbl sense, that is probably okay because sending is going to stop anyway, but some controllers can run jobs from SD cards and support multiple UI control channels, so reset-on-disconnect is not always ideal.

@cheton
Copy link
Collaborator

cheton commented Feb 20, 2023

Windows doesn’t properly drive DTR (set on connect, clear on disconnect) like other OSes do, but it does honor it internally and confusingly, meaning that if DTR isn’t set, RTS isn’t transmitted. See bug here.

On the other OSs hupcl is the actual setting passed to the OS, and does as it says in their docs: clear DTR when disconnecting, which is also something you want.

It is worth noting that the hupctl option is enabled by default. However, I have always encountered issues when connecting to Arduino Due on Windows without triggering DTR. This problem may also occur on macOS in rare cases, but it is not always reproducible.

https://serialport.io/docs/api-bindings-cpp#open

image

image

To address this issue, it may be beneficial to provide users with an option on the UI to choose whether they want to send a reset signal while opening the serial connection. This would enable users to control the behavior of their connections to their specific needs and operating system, helping ensure communication with devices like the Arduino Due.

@cheton
Copy link
Collaborator

cheton commented Feb 21, 2023

Hi all,

I would like to add a checkbox (which is unchecked by default) with the label Enable the DTR line when the serial connection is opened 🛈 on the Connection widget to provide users with more control over the serial connection. An info icon 🛈 will be placed at the end to provide additional information about what DTR is.

Do you have any suggestions or feedback on this implementation?


The option on the Connection widget:

[ ] Enable the DTR line when the serial connection is opened 🛈

Sample code:

if (enableDTR) {
  await delay(100); // Wait 100ms before setting the DTR line
  await port.set({ dtr: true });
}

// Wait for the reset to complete before continuing with other operations
await delay(1000); // <- The actual delay may vary with different controllers or hardwares

@cheton
Copy link
Collaborator

cheton commented Mar 30, 2023

The connection issue will be resolved in PR #813. You can set either DTR or RTS line status upon opening to resolve this issue.

image

I will release a new version 1.10.2 before the end of this week.

@cheton
Copy link
Collaborator

cheton commented Mar 31, 2023

A new version of CNCjs, version 1.10.2, has been released and is now available for download.

To get the latest version, visit the following links:

If you've encountered issues with serial communication when opening the application, you can try using either the Set DTR line status upon opening or Set RTS line status upon opening option. Just follow the instructions in the screenshot below:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants