Closed Tiktiki closed 1 year ago
Versions please, from $I
output. Also which version of Teensyduino you are compiling with, pre 1.54 is buggy.
There are two USB options - either PRJC or Arduino library code, are both behaving the same?
Firmware was compiled this week, most likely latest.
I am using VS Code, not in front of the PC right now. I am not certain what driver it uses by default. I would think Arduino since I didn't install a separate driver.
Will check all this later.
It might also be hitting the max block process limit of the hardware. I was cutting at 84ipm and didn't check what tolerance I set for smoothing, it might be feeding too much.
Is there a debug/verbose mode that can reply what exactly was received on errors? Would help figure out what happens...
If you have a UART <> USB breakout you can send debug messages to the UART port by uncommenting this line. debug_write() can then be used to send messages.
If you want to send what has been received you can do that here by calling
debug_write(line);
debug_write(ASCII_EOL);
What is your hardware setup? Which board? Are you using a VFD?
I am dealing with this as well on a new machine build. When we had data errors like this in the past on a previous build (connected to a VFD) it was mitigated by using a USB isolator and resolved by switching to Ethernet - neither of which are currently installed on my new machine as I wait for delivery of some parts. So I am currently blaming it on EMI from the VFD.
If you have a UART <> USB breakout you can send debug messages to the UART port by uncommenting this line. debug_write() can then be used to send messages.
If you want to send what has been received you can do that here by calling
debug_write(line); debug_write(ASCII_EOL);
Actually there is a line you can uncomment in config.h, it echos everything back to the console. It seems I didn't have SD enabled in the firmware I had, and after flashing it with everything (SD/FTP/WebUI) it did not cause the issue anymore, either with SD or USB.
I also suspect interference but since I couldn't reproduce it anymore...
What is your hardware setup? Which board? Are you using a VFD?
I am dealing with this as well on a new machine build. When we had data errors like this in the past on a previous build (connected to a VFD) it was mitigated by using a USB isolator and resolved by switching to Ethernet - neither of which are currently installed on my new machine as I wait for delivery of some parts. So I am currently blaming it on EMI from the VFD.
Right now, Makita router, shielded cables everywhere (except USB, I don't have a shielded one long enough for now). Servo-steppers (encoder-position/hybrid) NEMA24
Even if I am not using a VFD, that Makita router has electronic variable speed (basically a cheap VFD) so it's probably noisy.
I was also suspecting an overflow of the buffer... I was posting a 3d flowline toolpath and forgot to lower the resolution... It was segmented to 0.0004"... My machine can do it mechanically but it might be too much for the Teensy at 100ipm
Following up on this, today I switched the machine over to Ethernet and I have run the cycle that was causing me problems 3 times now with zero errors. Seems very solid - this was my previous experience using USB vs Ethernet as well.
I was also suspecting an overflow of the buffer...
Which sender? If your own are you using the character counting method to ensure that the buffer does not overflow? Or sending line by line after recieving the ok
response?
It was segmented to 0.0004"... My machine can do it mechanically ...
That is 1 micrometer? You must have a high end machine to get that kind of accuracy.
... but it might be too much for the Teensy at 100ipm
I have seen USB transfer rates > 400 Kbytes/s in check mode with ioSender, and when planner buffer size is tuned very high feed rates can be achieved (> 50.000 mm/min) even when doing laser engraving with a lot of small line segments. FYI max. step rate is ~300 Khz.
Will just throw my hat in the ring here also..
I ran into what I assume is this same issue today. I got an error 33 part way through an engraving job, and initially assumed it was actually an arc tolerance issue in the G-Code.
But then I couldn't recreate it with the same code on another Teensy on my bench, and running the job again on the CNC - it failed once again but in a different spot.
My USB connection is from a Raspberry Pi in the same cabinet as the Teensy. Have ethernet connectivity to the Pi, which is running CNCjs. I would love to try Ethernet direct to the Teensy, but sadly IOSender isn't an option for me (no Windows machines in the house), and not sure what other senders support it?
My VFD mounting location and cable routing is a bit suspect at the moment, will have a go at improving that first..
@dresco Can you try running in check mode, this runs the code through the parser only (no motion). If this is ok then either there is code issues elsewhere or electrical interference.
@dresco Can you try running in check mode, this runs the code through the parser only (no motion). If this is ok then either there is code issues elsewhere or electrical interference.
Thanks Terje, I'm sure it must be something environmental to my router build, as running the same code between laptop & naked Teensy on my desk is much more reliable (just one error in a whole afternoon of re-running the same job).
I think I'll fire up a Windows VM this week, and see how it performs with IOSender over Ethernet instead of CNCjs over USB..
Have a testing update, but is very odd!
If I build without sdcard and ethernet support, then I see these errors intermittently. Am running an engraving test job (~40k lines of gcode, takes ~35 mins to run on my router), and I never get through the whole job without either error 2 or 33.
However, if I build with either (or both) of those plugins enabled, then the errors just disappear. I know that sounds super weird, but I've run dozens of tests today, and has been really consistent! Am at a bit of a loss to explain it though?
Btw, I was testing with no power to my cabinet. Teensy was powered from laptop USB, nothing else connected to it except the (unpowered) stepper drivers, and the various limit switches and inputs.
but is very odd!
Indeed, which version of Teensyduino are you compiling with? Have you run the job in check mode? Same result?
Am building using PlatformIO. All tests today were using their Teensy 4.12 package, which builds against teensyduino 1.53 (this is the version that's pinned in the current platformio.ini file).
I had previously been using the latest 4.13 package, which pulls in teensyduino 1.55. However, that one has compatibility issues with the SDCard plugin (see issue #15)..
I've not tried check mode yet (I just disabled power to all the moving parts), is there a $ command to enable it?
which builds against teensyduino 1.53
1.53 is flaky...
I had previously been using the latest 4.13 package, which pulls in teensyduino 1.55. However, that one has compatibility issues with the SDCard plugin (see issue #15)..
Can you build without SD card support and test?
I've not tried check mode yet (I just disabled power to all the moving parts), is there a $ command to enable it?
$C
$C
Ha, that runs quick ;) Still getting the error in check mode with 1.53..
Built & testing 1.55 without either plugin now, it ran through successfully in check mode multiple times, so will give it multiple runs in normal mode...
Still something flaky building with 1.55 I'm afraid.
With no vfd, sdcard, or network support, then it's stable. If I enable vfd, but without sdcard or network, then I see the random errors. If I enable vfd & network (still using USB connection), then it's also stable.
I can replicate this with a naked teensy on my desk, if you want I can send you the files?
I can replicate this with a naked teensy on my desk, if you want I can send you the files?
I want you to test with this modification first, it adds a reentrancy lock to the function polling for input data:
static void usb_execute_realtime (sys_state_t state)
{
static volatile bool lock = false;
static char tmpbuf[BLOCK_RX_BUFFER_SIZE];
if(lock)
return;
char c, *dp;
int avail, free;
lock = true;
if((avail = usb_serial_available())) {
dp = tmpbuf;
free = usb_serialRxFree();
free = free > BLOCK_RX_BUFFER_SIZE ? BLOCK_RX_BUFFER_SIZE : free;
avail = usb_serial_read(tmpbuf, avail > free ? free : avail);
while(avail--) {
c = *dp++;
if(!enqueue_realtime_command(c)) {
uint_fast16_t next_head = BUFNEXT(rxbuf.head, rxbuf); // Get next head pointer
if(next_head == rxbuf.tail) // If buffer full
rxbuf.overflow = On; // flag overflow,
else {
rxbuf.data[rxbuf.head] = c; // else add character data to buffer
rxbuf.head = next_head; // and update pointer
}
}
}
}
lock = false;
}
I want you to test with this modification first
No difference I'm afraid
Along those same lines though, that prompted me to build with the Arduino USB library instead - and that has been totally stable (have run the code 10+ times in check mode with no errors)
I have run a 186785 lines program in test mode with the PJRC library numerous times without issues with SD card and VFD enabled, compiled with Arduino and Teensyduino 1.54. PlatformIO is causing problems or the 1.55 version?
I have run a 186785 lines program in test mode with the PJRC library numerous times without issues with SD card and VFD enabled, compiled with Arduino and Teensyduino 1.54. PlatformIO is causing problems or the 1.55 version?
Is it still stable for you when built with VFD but without SD card or network? I have just rebuilt with 1.54 & still seeing the same errors on a naked teensy here..
fwiw, have been aircutting the same job on my router all afternoon (with the Arduino USB library), and it's been rock solid.
Just a bit more data..
I've added a line to protocol.c to echo what was received when gc_execute_block() returns an error, and it's always mangled. The received line is either truncated, missing a chunk out of the middle, or has a data from different lines merged into it!?
As an extreme example, this instance failed on line 8782, but the parsed line has gcode from lines 8730 & 8783 embedded within it. Almost like the buffer pointers have got messed up as the received data is being written?
[echo: G1X174.048162.000Y51.233Z-0.499I0.649J3.912Y100.622Z-0.499F799.998]
> G1 X174.048 Y100.805 Z-0.499 F799.998 (line=8782)
error:1 (Expected command letter)
I made the PJRC code fail with a different test file. Seems it does not like to be polled too often unlike the Arduino code. Reducing the poll frequency seems to help:
static void usb_execute_realtime (sys_state_t state)
{
static volatile uint32_t last_micros = 0;
static volatile bool lock = false;
static char tmpbuf[BLOCK_RX_BUFFER_SIZE];
uint32_t current_micros;
if(lock || ((current_micros = micros()) - last_micros) < 250)
return;
char c, *dp;
int avail, free;
lock = true;
last_micros = current_micros;
if((avail = usb_serial_available())) {
dp = tmpbuf;
free = usb_serialRxFree();
free = free > BLOCK_RX_BUFFER_SIZE ? BLOCK_RX_BUFFER_SIZE : free;
avail = usb_serial_read(tmpbuf, avail > free ? free : avail);
while(avail--) {
c = *dp++;
if(!enqueue_realtime_command(c)) {
uint_fast16_t next_head = BUFNEXT(rxbuf.head, rxbuf); // Get next head pointer
if(next_head == rxbuf.tail) // If buffer full
rxbuf.overflow = On; // flag overflow,
else {
rxbuf.data[rxbuf.head] = c; // else add character data to buffer
rxbuf.head = next_head; // and update pointer
}
}
}
}
lock = false;
}
Increasing the BLOCK_RX_BUFFER_SIZE to 128 speeds it up a bit. Can you test with this as well? You may try with changing the poll interval too - 150 fails for me. I have no idea what a safe value might be - so perhaps better to make the Arduino implementation default?
Afraid the poll interval didn't make significant difference in my bench setup, I went up to > 1000 uS, and still seeing the errors. Increasing BLOCK_RX_BUFFER_SIZE did speed things up at higher poll intervals, but I couldn't find a combination that was stable.
I would vote for making the Arduino implementation the default for now.
Increasing BLOCK_RX_BUFFER_SIZE did speed things up at higher poll intervals, but I couldn't find a combination that was stable.
Neither could I, and the failure frequency changed with different intervals. What bothers me is that enabling ethernet or sd card makes the issue go away. Why? Because additional MCU peripherals are enabled?
Can you try with enabling the OpenPNP plugin only?
Can confirm with just VFD + OpenPNP plugins enabled it appears stable, and also with just the OpenPNP plugin enabled. (Running against bare board in in check mode).
Replacing the init code with this is a "fix" when no plugins are enabled. Do we have a memory leak somewhere and setting hal.user_mcode.execute
prevents it causing the issue? Any ideas?
static void userMCodeExecute (uint_fast16_t state, parser_block_t *gc_block)
{
hal.stream.write("[MSG: Hi!]" ASCII_EOL);
}
const io_stream_t *usb_serialInit (void)
{
PROGMEM static const io_stream_t stream = {
.type = StreamType_Serial,
.state = { .is_usb = On },
.read = usb_serialGetC,
.write = usb_serialWriteS,
.write_char = usb_serialPutC,
.write_n = usb_serialWrite,
.enqueue_rt_command = usb_serialEnqueueRtCommand,
.get_rx_buffer_free = usb_serialRxFree,
.get_rx_buffer_count = usb_serialRxCount,
.reset_read_buffer = usb_serialRxFlush,
.cancel_read_buffer = usb_serialRxCancel,
.suspend_read = usb_serialSuspendInput,
.set_enqueue_rt_handler = usb_serialSetRtHandler
};
// usb_serial_configure(); // Done somewhere already - do not call again
txbuf.s = txbuf.data;
txbuf.max_length = usb_serial_write_buffer_free(); // 6144
txbuf.max_length = (txbuf.max_length > BLOCK_TX_BUFFER_SIZE ? BLOCK_TX_BUFFER_SIZE : txbuf.max_length) - 20;
grbl.on_execute_realtime = usb_execute_realtime;
hal.user_mcode.execute = userMCodeExecute;
return &stream;
}
Any ideas?
Nope, honestly I'm baffled! Am travelling for a few days now, but have laptop and a bare board for testing if necessary..
Compiler or linker bug?
It seems to me that the problem only shows up when
#define SPINDLE_RPM_CONTROLLED
is uncommented in grbl/config.h.
Changing these lines in driver.c to
#if USB_SERIAL_CDC
const io_stream_t *st = usb_serialInit();
stream_connect(st);
#else
seemingly makes it go away. I'll have to run many more tests to verify this but I have had enough madness for today...
I have committed the changes that seem to fix this. I have also spaced out polling of the PJRC USB input a little bit as this helps by not overwhelming the sender with ok responses in check mode. The transfer rate is still around 400 Kbytes (10.000 gcode blocks/lines) per second with agressive buffering enabled.
I have committed the changes that seem to fix this.
Thanks, will do some testing here..
That's looking stable for me now, thanks! (Just tested in check mode on a bare board)..
I get this error randomly in code.
Currently streaming through USB, I have to test with a SDCard to see if it's related to the USB.
Happens randomly in cycle, not always the same place.
Last time the error happened here, in the middle of a cut: