simon-jouet / ESP32Controller

ESP32-based 3D printer controller
120 stars 29 forks source link

I2S motor and FET issues #10

Closed vivian-ng closed 3 years ago

vivian-ng commented 5 years ago

As @simon-jouet mentioned in PR#6 about starting a new issue to discuss the I2S-related motor and FET issues, I have taken the liberty to open the issue.

I am also experiencing issues with the I2S stream for motors, similar to what @Ringel mentioned. Sometimes, after the motors have stopped, it will start to drift on its own (I see this on my X axis, which uses the pins 128, 129, and 130). I also had an experience where partway through a print, the X gantry just drifted toward X_MIN, and kept crashing into the endstop until I had to turn off the printer. It seemed random because I did the same print again and the print completed.

As for driving of FETs, I am able to drive my E0 MOSFET using pin 140, but I am not able to control my fan MOSFET using pin 141. I will check to see if using a pin from 144 and higher will give more consistent results.

I have horrible temperature reading fluctations of plus minus 5 degs, which could be due to noise from the I2S lines as mentioned by @felixstorm before. Will try to reroute the lines and add a ground plane below the I2S lines to see if it helps. Meanwhile, I had to set TEMP_HYSTERESIS as 10 to allow for printing to commence. Definitely not ideal, haha.

I haven't had any luck with trying to drive the LCD controllers via I2S, but will try to use the pins 144 and above to see if it works. If my understanding of what @simon-jouet is saying, the lower pins (128 to 143) should be used for the motors, while the higher pins (144 to 159) can be used for MOSFETs and LCD. Will give that a try.

simon-jouet commented 5 years ago

I am also experiencing issues with the I2S stream for motors, similar to what @Ringel mentioned. Sometimes, after the motors have stopped, it will start to drift on its own (I see this on my X axis, which uses the pins 128, 129, and 130). I also had an experience where partway through a print, the X gantry just drifted toward X_MIN, and kept crashing into the endstop until I had to turn off the printer. It seemed random because I did the same print again and the print completed.

Do you see it for the other steppers too are just X ? Because all the steppers are part of the same stream so I would assume that if it's something to do with I2S then all steppers would be jittering not just the X axis.

I have seen something similar to this in my first ESP32 prototype (without I2s) where the noise was triggering the stepper drivers when it shouldn't. If you have an oscilloscope put a probe on the step pin of the X driver to start with and check if you just get a peak or not. Then you can put a probe on SDI/WCLK/BCLK to see if you also see some noise.

but I am not able to control my fan MOSFET using pin 141.

IIIRC the fan in Marlin is a PWM output so it won't work over I2S as is. Considering the FAN speed is part of the planner block it might be possible to simulate a PWM signal using the I2S stream but that's not implemented yet.

I have horrible temperature reading fluctations of plus minus 5 degs, which could be due to noise from the I2S lines as mentioned by @felixstorm before. Will try to reroute the lines and add a ground plane below the I2S lines to see if it helps. Meanwhile, I had to set TEMP_HYSTERESIS as 10 to allow for printing to commence. Definitely not ideal, haha.

This points to roughly the same thing as the first point with the stepper moving just because of the noise. I will see how it looks with my new board hopefully the noise isn't too bad. What you can try in the short term is to reduce the noise of your board. If you have some aluminium or copper tape you can add some on top of the traces and create a grounds plane without have to reroute everything. Won't be pretty but at least you might be able to debug what's wrong.

I haven't had any luck with trying to drive the LCD controllers via I2S, but will try to use the pins 144 and above to see if it works. If my understanding of what @simon-jouet is saying, the lower pins (128 to 143) should be used for the motors, while the higher pins (144 to 159) can be used for MOSFETs and LCD. Will give that a try.

This can be configured but that's about it yes. In the current configuration the lower 16bits are buffered in the I2S DMA stream and are perfect for time critical operation (with a bit of latency), all the operations in this stream are scheduled every time the DMA buffers finishes a block. The higher 16bits are a constant I2S channel value which is read from an I2S register so this will change as soon as the value is written. However, the constant channel is not very accurate timing wise because it will happen at the next word transmission of the I2S depending on when the register was written too, so if you write too fast some data might never have been sent.

Ringel commented 5 years ago

The Motor drift was on all 3 Axis in my Delta configuration after a Z-move - looks like the last move was somehow sticky. I checked this with a scope on BCLK and SDI - there was a pulse every 32ms - and even after motor disable timeout the enable was still there for 4 BCLK's with a pulse within.

And i still have sometimes strange null output after 4ms - considering 250khz BCLK rate there might be something wrong every 1k/4k samples?!?

Noise might be an issue with my current design - we should consider some serial termination resistors to improve signal integrity. But Noise shouldn't be that regular - the error condition stays forever with constant frequency.

Temperatures are quite stable (using 22uf caps instead of 10us) - but having 26°C when breaking the wire won't trigger an exception. Maybe some voltage divider might give some more headroom for low temps.

BTW - got the FETs for heating up at I2S Output >16 .... but still having problems with the fan. Maybe because the HAL tells Marlin that there are no PWM Outputs above 34

vivian-ng commented 5 years ago

For PWM implementation on I2S, will this library be good reference? CryptoIO In its analogwrite() and run() methods. Basically, the run() method seems to be the one that decides the 1 and 0 values for each bit in the register. For an analog output bit, every 256 cycles, it is set to 1 for the number of cycles equal to its "PWM" value.

As for temperature readings, I will try out with a 22uF capacitor to see whether I get more stable readings.

Regarding noise affecting the stepper motors, I didn't really notice on Y and Z axis, but Z is on a lead screw so any small stray steps may be too small to notice, which Y is a bed and the stray steps may not create enough torque in the first place. Will try to hunt down some copper tape...

simon-jouet commented 5 years ago

The Motor drift was on all 3 Axis in my Delta configuration after a Z-move - looks like the last move was somehow sticky. I checked this with a scope on BCLK and SDI - there was a pulse every 32ms - and even after motor disable timeout the enable was still there for 4 BCLK's with a pulse within.

I've got a faint memory of a potential issue when the I2S data stream was set high for the last word of the buffer (because then there was no buffer afterwards to set it low). Might be something like that, might be a bit hard to replicate.

Every 32ms would map to that, each buffer is 4k in size and therefore contains 1k samples. At 250khz the 32ms would be the 8 buffers in the dma repeating again and again when there are no movements. I will have a better idea when I get my board (and if i can replicate it)

BTW - got the FETs for heating up at I2S Output >16 .... but still having problems with the fan. Maybe because the HAL tells Marlin that there are no PWM Outputs above 34

Marlin expects hardware PWM, and doing PWM over I2S would effectively be software.

For PWM implementation on I2S, will this library be good reference?

Potentially, although coding the PWM over I2S is fairly straightforward just needs some time. If you want a very basic PWM over i2s you just need to set x out of 256 bit high when scheduling the stepper steps. x in that case will be the duty cycle.

Ringel commented 5 years ago

The drift issue should be fixed if the DMA buffer is filled completely like https://github.com/Ringel/Marlin/commit/9a50f1ffbc83878bbb247522eb7a4da8db8b1b05 Wasn't able to reproduce the drift with this patch.

@simon-jouet do you still have the 16Bit DMA/16Bit Register configuration? Only found a 16Bit-Only in esp32-i2s and the 32Bit DMA in esp32-i2s-dma

felixstorm commented 5 years ago

@vivian-ng I personally use I2S pins for fans, but only for the controller and the hotend fans, so no PWM here. But when browsing the code to find out how these fans work, I did stumble across the define FAN_SOFT_PWM. And from a quick look at the code this should probably do exactly what you are looking for also for the part cooling fan and I do not see any reason why it should not work on the ESP32...

@Ringel Thanks for your fix. I will try it out when I do my next prints - unfortunately I do not have much spare time at the moment.

simon-jouet commented 5 years ago

The drift issue should be fixed if the DMA buffer is filled completely like Ringel/Marlin@9a50f1f

@Ringel Thanks looks good, I don't remember well enough right now why this was done this way, but using a while looks cleaner anyway. From the looks of it I omitted that at the end of the moves stepper_pulse_phase_isr didn't push anything to the buffer. Thanks for the patch, if @felixstorm and @vivian-ng report that it's working better you should probably create a MR for Marlin?

@simon-jouet do you still have the 16Bit DMA/16Bit Register configuration? Only found a 16Bit-Only in esp32-i2s and the 32Bit DMA in esp32-i2s-dma

I thought it was the default config in Marlin that I had pushed but it doesn't look like it. @vivian-ng sorry about that I might have told you the wrong thing before. I will have to check my sample code see if I still have it somewhere. IIRC you need to change tx_chan_mod to 3 or 4 (https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf chapter 12) and write to I2S0.conf_single_data

But when browsing the code to find out how these fans work, I did stumble across the define FAN_SOFT_PWM. And from a quick look at the code this should probably do exactly what you are looking for also for the part cooling fan and I do not see any reason why it should not work on the ESP32...

That's good news, coding it wouldn't have been too bad but if it's built in it's even better

vivian-ng commented 5 years ago

@felixstorm Have you tried to see if FAN_SOFT_PWM would work for the part cooling fan as well running on I2S? I believer PWM values can be used for CONTROLLER_FAN and E0_AUTO_FAN, have you set them to some value other than 255 to see if there is a difference when FAN_SOFT_PWM is enabled? I will also try to find time to test this out.

For soft PWM to work on I2S pins, there will be a need to change HAL.cpp so that the check for PWM pins is p < 34 || p > 127 right?

Ringel commented 5 years ago

From the looks of it I omitted that at the end of the moves stepper_pulse_phase_isr didn't push anything to the buffer.

Yes - and if idle there are 4x stepper_pulse_phase_isr (counted but not pushed something) that caused the remaining 4 samples in the buffer to stick.

IIRC you need to change tx_chan_mod to 3 or 4 and write to I2S0.conf_single_data

4 did the trick - see https://github.com/Ringel/Marlin/commit/cdf3b84e5bda0038e38604962e94f94b22d4968f for working split DMA/register writes.

I first checked if the Display now works from the i2s extender ... unfortunately the LiquidCrystal library used digitaWrites instead of Marlin HAL. Getting 6 precious IOs back from the esp might be worth the fix ;)

But when browsing the code to find out how these fans work, I did stumble across the define FAN_SOFT_PWM.

FAN_SOFT_PWM works for the part fan ... E?_Auto_FAN an CONTROLLER_FAN still needs hardware PWM Maybe we should write the PWM pattern to the DMA buffer when finished ... unfortunately now i have the FANs on register-i2s pins... so software PWM for all fans would be nice.

For soft PWM to work on I2S pins, there will be a need to change HAL.cpp so that the check for PWM pins is p < 34 || p > 127 right?

Tried that - but returning PWM feature expects hardware PWM (at least done by HAL) and does not switch to software PWM

felixstorm commented 5 years ago

@vivian-ng No, I have not tried it myself yet as my part cooling fan is connect to a direct GPIO.

@Ringel Ok - I had only looked for the part cooling fan. But what does work for me is to just run them on full speed from the I2S outputs as both will switch to a normal WRITE for non-PWM pins (see my config, auto fan and controller fan).

Ringel commented 5 years ago

But what does work for me is to just run them on full speed

Yes - but i'm used to reduce the fan noise of all fans. For that i've changed PWM from ledc-hardware to software timer, to be able to handle direct and register-i2s outputs in the HAL with the following changeset: https://github.com/Ringel/Marlin/commit/8515126fa8ba8b9a024092bfb269fcd8b7ead1ad

Hardware-PWM might be more ressource friendly - but was double used by the servo HAL anyhow.

Running PWM on the DMA outputs would also be nice ... but i'think i'll first try to get the display via the i2s register-pins up.

vivian-ng commented 5 years ago

Quick recap: Stepper motors are already working. "Digital" pins for turning on and off fans are working.

My "to test":

  1. I2S for bed and hotend heating
  2. Fan PWM control with FAN_SOFT_PWM
  3. I2S for SPI chip select pins (SD card's SDSS, maybe TMC2130's CS pins)
  4. BEEPER_PIN With 32 output pins, there are just too many options for using them. 😅

@Ringel Will you be pushing those changes to the main Marlin repo anytime soon? Even if LCD is not working, any improvements to the current HAL would be great. Getting LCD to work would be great since it will free up at least 3 pins (LCD_ENABLE, LCD_RS, LCD_D4).

Also, has anyone tried using 74HCT595 (TTL version)? Does it really make such a difference?

simon-jouet commented 5 years ago

@Ringel Will you be pushing those changes to the main Marlin repo anytime soon? Even if LCD is not working, any improvements to the current HAL would be great.

Yeah pushing the fix for the i2s stream would be great. However, I don't think the constant channel for the top 16 bits should be pushed. That will be board dependent, if we want this we should probably set it behind #define so we can change from one mode to another

Ringel commented 5 years ago

I don't think the constant channel for the top 16 bits should be pushed. That will be board dependent, if we want this we should probably set it behind #define so we can change from one mode to another

You're right - added I2S_STEPPER_SPLIT_STREAM to enable. PR see https://github.com/MarlinFirmware/Marlin/pull/14592

simon-jouet commented 5 years ago

Thanks @Ringel, I think my only comment on your MR is that it replaces all ledc with the timer which is not something some people might want (for instance no I2S or I2S but no constant channel).

Another reason why I'm not a big fan of this is that the ledc PWM is significantly more efficient than timer based and timers do cause problems with the WiFi (which is why I'm trying to use them as least as possible). I've got a PoC of switching the temperature ISR to a task in order to remove the need for all timers.

https://github.com/MarlinFirmware/Marlin/pull/14592

EDIT: thinking about it we probably should not use the timer for ESP32's pins, ledc can be attached to any of the ESP32 pin so the logic here is only needed to do PWM over I2S. The logic you have could potentially be just in a #define I2S_TIMER_PWM ?

I think a sanity check will be required to have I2S_TIMER_PWM only valid if I2S_STEPPER_SPLIT_STREAM is enabled. And i think remove the iteration in the analogWrite would be quite beneficial

Ringel commented 5 years ago

Having FAN_SOFT_PWM for all fans could remove need for this too. But the scheduling of ledc channels between PWM and servos should be resolved

simon-jouet commented 5 years ago

Yeah, can't remember who added the servo code, but we should probably review/refactor the existing code so there is no conflcit with the ledc channels

felixstorm commented 5 years ago

@Ringel I agree that having FAN_SOFT_PWM for all fans would probably have the same effect and would have the added benefit of bringing the additional functionality to all Marlin platforms.

@Ringel, @simon-jouet I am not so much worried about PWM and servos interfering as I purposely starting allocating pwm channels for servos from channels 12 up only. That leaves room for 12 fans, RGB channels etc. before there would be a conflict (and will still support 4 servos).

simon-jouet commented 5 years ago

@felixstorm yeah that makes sense, it might be good to add a check in analogWrite() just for sanity?

Just realised something going through the code, I never pushed my improved temperature code. In the current code the attenuation is always at 11DB so we are losing in precision. I had modified this code to automatically shift the attenuation to have more precision ... I will have to check where I have that and probably modify it to cope with the upstream modifications... (that would also explain why people were saying they had big temperature delta while I didn't - noise was just part of the problem)

simon-jouet commented 5 years ago

I couldn't find the temperature code I wrote before so just rewrote it. Gave it a test on one of the R1 board and it's working fine. This should give much better temperature measurement (still doesn't solve the ~25degree min temp)

@vivian-ng might be good if you could try considering you're the one with the biggest temperature variation. It would be useful to know which revision of the ESP32 you're running, it should say in platformIO when you upload e.g Chip is ESP32D0WDQ6 (revision 1)

@felixstorm, @Ringel if you could try as well that would be great!

The code is on my Marlin repo https://github.com/simon-jouet/Marlin/commits/esp32 (latest bugfix-2.0.x as of tonight)

On a side note it anybody having issues with OTA? it's not working for me (it used to work fine). I also tried the WebSocket serial, and I don't know what changed but it barely works now, M114 works but M115 looks to be crashing the socket.

vivian-ng commented 5 years ago

@simon-jouet Okay, will download your HAL.cpp and give it a try as soon as I can. A bit busy with other work lately.

I am actually using @luc-github's Marlin fork, which allows use of his ESP3D webUI. He has been working hard on making sure it is in sync with the main Marlin repo and all the updates there, and recently has been asking about how his work can be integrated back into the main repo. There will probably be some work to delete/add the changes in your HAL.cpp to fit into the one that luc has; hopefully not that much work so that I can get down to testing earlier.

Side note: luc's Marlin fork has OTA working fine, and the webUI (which, in addition to a serial terminal for sending commands to the ESP32, has other buttons and such for moves, heating, fan control, file upload, etc.) has been tested to be working more or less fine. Some minor issues here and there, such as the temperature graph not updating when the ESP32 is busy with heating. But overall, more than adequate. At least enough for me to use my first prototype board (no I2S) to be used without an LCD controller; just use a smart phone or PC.

EDIT: thinking about it we probably should not use the timer for ESP32's pins, ledc can be attached to any of the ESP32 pin so the logic here is only needed to do PWM over I2S. The logic you have could potentially be just in a #define I2S_TIMER_PWM ?

Fully agree with the ledc timer issue. A #define I2S_TIMER_PWM will definitely help. Design-wise, I think a new feature does not necessarily replace an existing one if the existing feature works. Users then have the choice of sticking with the old feature, or hopping onto the new one.

simon-jouet commented 5 years ago

I am actually using @luc-github's Marlin fork, which allows use of his ESP3D webUI. He has been working hard on making sure it is in sync with the main Marlin repo and all the updates there, and recently has been asking about how his work can be integrated back into the main repo. There will probably be some work to delete/add the changes in your HAL.cpp to fit into the one that luc has; hopefully not that much work so that I can get down to testing earlier.

Luc's HAL is based on mine (and now the upstream Marlin) so a large chunk of the HAL code should be the same which should make bringing those changes easy.

I've seen Luc's issue on Marlin but I think instead of entry point a large chunk of his changes could be brought directly in Marlin (for instance all the new gcode). It's probably just a matter or cherry picking the features one by one and creating (and reviewing) MRs on Marlin. Also my end goal (and Grownseed) when we wrote the web stuff was to potentially define a reasonable API in Marlin and then you can use whatever UI you want. Any web UI will need movement, file upload so most code can be brought in without requiring an entry point for the handlers. If entrypoints are required then it might be good to look at the lcd code who uses them already.

luc-github commented 5 years ago

@simon-jouet this is what I do in ESP3D since the begining - the ESP3D-WEUI is not part of fw and same is used for GRBL_ESP32, but some feature are not in UI like telnet / email or push notification / DHT support, etc..

Other people developed their own webUI already. and no need to modify ESP3D

luc-github commented 5 years ago

why I suggested an entry point is because some decision like using SPIFFS for EEPROM (which is strange for me) instead of EEPROM NVS (what I did and seems better if user want to use FAT instead of SPIFFS), or need to have better access to serial than existing one for bridging, etc, I did not want to break what have been done and as I wrote it is just a proposal / discussion to propose other access - if it is not in plan I am fine ^_^

simon-jouet commented 5 years ago

SPIFFS for EEPROM (which is strange for me) instead of EEPROM NVS

I also think that NVS might make more sense than SPIFFS, we could always check with @Idorobots and change it if we agree. It's still early days of the ESP32 so it might be better to change things like this now than later.

For the other things i'm not sure what the status is at the moment, some people have reported OTA and websocket working for them, they definitely used to work for me but I pulled the most recent version and it's not working (can't upload using OTA (might need to double check my config) and the websocket is very buggy)

if it is not in plan I am fine ^_^

I really don't know what the plan is for Marlin :), it might be good to have a small sample in your PR issue so @thinkyhead can have a look and give his opinion

luc-github commented 5 years ago

@simon-jouet, About features additionally ESP3D use sync WebServer, for 3 reasons : 1 - the developer is overloaded and cannot always give support,
2 - per my personnal experience with more than 4 years on ESP and Sync/ Async webserver - async is not yet always stable and reliable for intensive usage, same for websocket used by this lib, I push PR time to time on it and I know well the dev which is in charge also of ESP32. 3 - on GRBLesp32 it was reported that during async call motor has some jitter, so I moved definitively to Syncwebserver and links2004 socket library and no issue at all. GRBL may be more sensitive than Marlin but I prefered play safe. About plans: I do not know the Marlin plans neither that is why I posted issue/ FR to get some feedback / direction, to know if it worth to spend time on such PR or not, intgration or entry point, but if no one spend time on answering when full code is already available - do you think anyone will spend time on trying a PR ? I understand Marlin Dev are overloaded that is why I initiated discussion instead of spend time on dead end solution what ever it is ^^

Idorobots commented 5 years ago

@simon-jouet @luc-github I do agree that NVS makes more sense for EEPROM backing, I whipped up a SPIFFS implementation in Marlin in a hurry without giving it much thought just to get to a working state quickly. :)

felixstorm commented 5 years ago

@luc-github I also saw your issue and also was quite disappointed that nobody reacted on it officially. Maybe you could try to address thinkyhead directly as apparently he has one of @simon-jouet's first-generation board himself (see https://github.com/MarlinFirmware/Marlin/issues/14345#issuecomment-505430487) and always was pretty fast merging my ESP32-related PRs.
Or maybe @simon-jouet has connections that he could use to check for what strategy would be for Marlin to support integrated WiFi?

And if there still does not come any official reaction, we might just agree for your fork to be our internal "official" one then for now? Looks like everybody that is actually using Marlin on the ESP32 is taking part in this issue :wink:

@simon-jouet I will definitely test your temperature code. I will very soon be out for vacation for 2 weeks or so but hopefully still make one larger print before.

simon-jouet commented 5 years ago

@luc-github we can probably bring those changes in the ESP32 branch, barely anybody uses that at the moment and if it's an improvement and stays within the ESP hal it should make it through.

For the stepping there shouldn't be any jitter when i2s is used, I guess with the timer ISR it might be an issue. I remember having some issues dealing with the WiFi code when the timers were used.

Having the Gcode to configure the WiFi built into marlin would clearly be useful, reflashing just for the SSID and password doesn't make much sense. (I wrote it that way because getting WiFi to work was very low prio in the original HAL)

I think the entry might still make sense, depending on the web UI used some new endpoints might be required and adding a way to extend the http handlers might be useful (which is I think what you were saying in your FR?). Like I said in the previous comment it might be worth checking how the extensible lcd code works and use something similar?

@Idorobots thanks, good to know :) should be easy to get that switched then!

@felixstorm yeah thinkyhead has one of the R1 board and I will send him an R2 board once they are working (still waiting on the PCB and some components). From what I've seen he his quite pragmatic, if it's an improvement for Marlin that doesn't hinder anything existing. I don't know him though, so that's just my impression :). No particular connections no, same as everybody here, mostly github and very briefly on discord.

The problem with the fork (which is why i'm trying to avoid that if possible) is that it's much more pain to maintain and it won't help new people/companies adopting the ESP32 which isn't really in our best interest.

If we all agree on some things that are better for the ESP32 hal then I think it will be merged in (as long as it stays within the ESP32 HAL). If Marlin decides to stop supporting the ESP32 for whatever reason they can just delete the folder and call it done. All the current WiFi code is either from my initial MR or my brother (grownseed) and fixes from @Idorobots so it's quite limited and can be easily replaced with something else.

@simon-jouet I will definitely test your temperature code. I will very soon be out for vacation for 2 weeks or so but hopefully still make one larger print before.

Thanks, curious to hear feedback. I need to tweak it a bit before opening an MR in Marlin but the current code should be fully operational.

felixstorm commented 5 years ago

Please don't get me wrong - I'm not for a fork either. It was just meant as a last resort for some time until the Marlin maintainers e.g. have released 2.0 and have a bit more time again.

luc-github commented 5 years ago

@Idorobots, sorry I did not react when you pushed your PR as I am not watching Marlin git, I was overflowded with Marlin notifications and I unsuscribed a while ago, and still unwatch, I just react when my name is mentionned ^_^. @simon-jouet Yes my FR was an open discussion - because I think it useless to start anything if it is a no go, so I asked first.

@felixstorm, yes it is not my plan neither to maintain a long term Marlin's fork, I just did it to have full tested solution before proposing a PR to Marlin. I rebase on demand without issue until then.

About @thinkyhead, I think he is busy and does not need a new reminder because @vivian-ng already did it and he is definitly aware of ESP3D since @Grownseed PR as I was mentionned on it and answered, and he recently watched a youtube video about it and commented it. 😸. But you can do some lobbying , I am ok. ^_^

That said,sSorry @simon-jouet to hack your thread with such unrelated issue - but I happy to learn steppers are better with i2s

felixstorm commented 5 years ago

@simon-jouet An almost 12 hour PETG print (that had a large layer shift on a previous attempt a week or two ago) finished nicely and without any problems on my ESP32 Ender-3 this morning (with I2S fix https://github.com/Ringel/Marlin/commit/9a50f1ffbc83878bbb247522eb7a4da8db8b1b05 and with your new temperature code). Some stringing, but that's definitely neither Marlin's nor the ESP32's fault :wink:.

@luc-github I would just go ahead and file some small separate PRs - starting with the ones entirely inside the ESP32 HAL, e.g. one replacing EEPROM SPIFFS with NVS, another one with your synchronous WebServer implementation (as an alternative using #ifdefs) and then wait for them to be merged. If that's done, then file the last one offering a general method for HAL-specific g-code (maybe similar to the way HAL_INIT used to work before it had been made mandatory) and containing your ESP3D specific g-codes again inside ESP32 HAL.
And if there should be no reaction, then I'd be happy to comment and agree on the pull requests and maybe @simon-jouet, @Idorobots and some others could do the same.

I'll be off for vacation more or less today for almost 3 weeks, but I'll try to monitor the discussion on my mobile if I have a chance (just copy me on any new issues or PRs). And looking forward to coming back and trying out Marlin with ESP3D integrated - maybe already from https://github.com/MarlinFirmware/Marlin or from https://github.com/luc-github/Marlin

Kind regards, Felix

vivian-ng commented 5 years ago

@simon-jouet I have tested the new ADC code, without a thermistor connected and using 4.7K pullups, the reading was around 25 degC. With room temperature at around 28 degC, I get a reading of 30 degC when I connect a thermistor to my non-I2S board. With my I2S board, I get something like 35 degC instead.

Temperature reading fluctuations on both boards seem to be around 1 to 2 degC, but I still needed to set TEMP_HYSTERESIS as 5 (default is 3) in order to be able to start a print.

PWM on I2S pins work. Or at least I think they work. I connected one of them to a LED, and at various output values, the LED changed in brightness.

I2S pin can also be used for LCD's beeper. But no luck trying to get it to work with LCD_ENABLE, LCD_RS, or LCD_D4.

Oh, trying to use 1K pullups for the thermistors doesn't really work too. At room temperature, with or without a thermistor connected, using a 1K pullup will give a temperature reading of 68 degC.

vivian-ng commented 4 years ago

Two separate issues:

  1. Linear advance. I couldn't get linear advance to work with I2S motor stream. This was about two months back, so new fixes might have already sorted this out. Just wondering if anyone else had similar situation. Basically, when linear advance is enabled, the motors will just refuse to move.

  2. Babystepping/manual mesh bed leveling with TMC2130. When I try to babystep during a print, the board will reboot once I try to change the Z height. When I try to do a manual mesh bed leveling, the board will reboot after it has homed the three axes. This did not happen when I was using A4988 drivers.

Any suggestions on where to start looking to see how to fix these issues?

felixstorm commented 4 years ago

@vivian-ng - unfortunately I do not have solutions, just my experience:

In addition to your findings I have some more nuisances:

But all in all these were just a bit annoying and not a real problem. And since unfortunately I currently have little spare time, I also was not able do research on what might cause the issues.

vivian-ng commented 4 years ago

@felixstorm

  1. I think there is some issue with the babystepping code that causes the reboot, since manual mesh bed leveling also uses the babystepping to adjust nozzle height for each point being sampled. I will take a look at the code when I have time to see if I can narrow down the issue. It probably has to do with how the code calculates stepper pulses, since I2S stepper stream has a limit of 250,000 pulses (if I recall) and the firmware may be rebooting because of value error or something.

  2. I have not been observing my prints, so I can't say if they are stopping mid-print. When I was using A4988 stepper drivers, I never noticed a stop in the noise during prints (3 to 5 hours long). But I switched to test TMC2130 stepper drivers on X and Y... so it is so quiet now, I won't even notice if there are actually stops.

  3. My printer is located in the next room, and I usually print via the web interface that @luc-github uses, so I might have missed the screen stopping or freezing. My main issue with the screen is the poor contrast and brightness. But that is not a show stopper.

vivian-ng commented 4 years ago

@felixstorm I did a bit more testing.

  1. Manual mesh bed leveling works via gcode (I am using @luc-github fork, and used G29 S1 and other gcodes to achieve the bed leveling). Trying to use the LCD controller, whether TMC2130 or A4988 drivers, would cause a reboot after the initial homing.

  2. Babystepping (gcode M290) does not work. I tried using the suggested changes here, but that did not work too. Babystepping via LCD controller will cause a reboot the moment I move the knob to change the Z height.

  3. Linear advance doesn't work with I2S, I will try to find time to look at the code to see why. It works on the ESP32 without I2S. So there is something about how linear advance and I2S are implemented that's cause the extruder motor to not move.

If anyone has any suggestion on how to test ESP32 with ILI9341 display, do let me know. I have a M5Stack which I want to use to test this. It has three buttons, which can be used to simulate buttons up, down, and enter.

vivian-ng commented 4 years ago

Has anyone tried using I2S on a coreXY setup? I am facing random resets during homing. The resets happen either when changing direction along the same axis (such as when it has reached the X endstop, and is reversing direction for X_HOME_BUMP_MM) or when changing axis (such as after X and Y axes have homed, and it is switching to move Z axis for homing).

On a ESP32 board that does not use I2S (only native pins), I do not have such random resets on my coreXY setup. Also, on a cartesian printer, I do not observe such random resets when using I2S for the stepper stream, so I suspect it has to do with the combination of coreXY mechanics (which requires both X and Y motors to move and change directions) and the use of I2S stepper stream. Wondering if anyone else has experienced such an issue.

reddomon commented 4 years ago

Hi, i have same issue mentioned before in my post. İ tried raw cartesian mode and doesnt occur any brownout reset. But when i use i2s core xy browout reset occurs randomly when touching home switches.

vivian-ng commented 4 years ago

This is the error that triggered the reboot when homing using a coreXY setup.

PC      : 0x400f418e  PS      : 0x00060931  A0      : 0x800f2abd  A1      : 0x3ffbe620 
A2      : 0x00000000  A3      : 0x00000001  A4      : 0x3f000000  A5      : 0x00000000
A6      : 0x00000000  A7      : 0x3ffde474  A8      : 0x800f4188  A9      : 0x3ffc3080 
A10     : 0x00000000  A11     : 0x3ffdea38  A12     : 0x4000bff0  A13     : 0x3ffbe7c0 
A14     : 0x00002aaa  A15     : 0x00000000  SAR     : 0x00000020  EXCCAUSE: 0x00000004
EXCVADDR: 0x00000000  LBEG    : 0x40002390  LEND    : 0x4000239f  LCOUNT  : 0x00000000  
Core 1 was running in ISR context:
EPC1    : 0x400f418e  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x40082a51
Backtrace: 0x400f418e:0x3ffbe620 0x400f2aba:0x3ffbe700 0x400f15a6:0x3ffbe720 0x400f1613:0x3ffbe740 0x400f509f:0x3ffbe760 0x400f50bf:0x3ffbe780 0x40080fa5:0x3ffbe7a0 0x40081859:0x3ffbe7c0 0x4000bfed:0x3ffb1c40 0x40089d2d:0x3ffb1c50 0x4008babf:0x3ffb1c70 0x4008c144:0x3ffb1c90 0x40084a74:0x3ffb1cb0 0x40084aa9:0x3ffb1cd0 0x4008618d:0x3ffb1cf0 0x4000beaf:0x3ffb1d10 0x4016a7af:0x3ffb1d30 0x4016a781:0x3ffb1d50 0x400fac07:0x3ffb1d70 0x400ff61e:0x3ffb1db0 0x400e1056:0x3ffb1dd0 0x400e0cdd:0x3ffb1df0 0x400d311b:0x3ffb1e10 0x400e1358:0x3ffb1e30 0x400f2bae:0x3ffb1e50 0x400f1e77:0x3ffb1e70 0x400f1f3a:0x3ffb1ed0 0x400e3295:0x3ffb1f00 0x400e4b0b:0x3ffb1f30 0x400e52ad:0x3ffb1f50 0x400e695c:0x3ffb1f70 0x400e15c5:0x3ffb1f90 0x40107529:0x3ffb1fb0 0x400884a5:0x3ffb1fd0

This is the decoded stack:

PC: 0x400f418e: Stepper::endstop_triggered(AxisEnum) at Marlin/src/module/stepper.cpp line 2228
EXCVADDR: 0x00000000

Decoding stack results
0x400f418e: Stepper::endstop_triggered(AxisEnum) at Marlin/src/module/stepper.cpp line 2228
0x400f2aba: Planner::endstop_triggered(AxisEnum) at Marlin/src/module/planner.cpp line 1489
0x400f15a6: Endstops::update() at Marlin/src/module/endstops.cpp line 706
0x400f1613: Endstops::poll() at Marlin/src/module/endstops.cpp line 268
0x400f509f: Temperature::isr() at Marlin/src/module/temperature.cpp line 2800
0x400f50bf: tempTC_Handler() at Marlin/src/module/temperature.cpp line 2324
0x40080fa5: timer_isr(void*) at Marlin/src/HAL/HAL_ESP32/HAL_timers_ESP32.cpp line 75
0x40089d2d: vTaskExitCritical at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/tasks.c line 4274
0x4008babf: multi_heap_internal_unlock at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap.c line 380
0x4008c144: multi_heap_malloc at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap_poisoning.c line 202
0x40084a74: heap_caps_malloc at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/heap_caps.c line 111
0x40084aa9: heap_caps_malloc_default at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/heap_caps.c line 140
0x4008618d: _malloc_r at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/newlib/syscalls.c line 37
0x4016a7af: operator new(unsigned int) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/new_op.cc line 50
0x4016a781: operator new[](unsigned int) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/new_opv.cc line 32
0x400fac07: WiFiUDP::parsePacket() at /home/user/data/platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/WiFiUdp.cpp line 210
0x400ff61e: ArduinoOTAClass::handle() at /home/user/data/platformio/packages/framework-arduinoespressif32/libraries/ArduinoOTA/src/ArduinoOTA.cpp line 382
0x400e1056: WiFiServices::handle() at Marlin/src/HAL/HAL_ESP32/wifiservices.cpp line 133
0x400e0cdd: WiFiConfig::handle() at Marlin/src/HAL/HAL_ESP32/wificonfig.cpp line 423
0x400d311b: HAL_idletask() at Marlin/src/HAL/HAL_ESP32/HAL.cpp line 84
0x400e1358: idle(bool) at Marlin/src/Marlin.cpp line 697
0x400f2bae: Planner::synchronize() at Marlin/src/module/planner.cpp line 1541
0x400f1e77: do_homing_move(AxisEnum, float, float) at Marlin/src/module/motion.cpp line 1249
0x400f1f3a: homeaxis(AxisEnum) at Marlin/src/module/motion.cpp line 1435
0x400e3295: GcodeSuite::G28(bool) at Marlin/src/gcode/calibrate/G28.cpp line 327
0x400e4b0b: GcodeSuite::process_parsed_command(bool) at Marlin/src/gcode/gcode.cpp line 244
0x400e52ad: GcodeSuite::process_next_command() at Marlin/src/gcode/gcode.cpp line 830
0x400e695c: GCodeQueue::advance() at Marlin/src/gcode/queue.cpp line 880
0x400e15c5: loop() at Marlin/src/Marlin.cpp line 1159
0x40107529: loopTask(void*) at /home/user/data/platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp line 19
0x400884a5: vPortTaskWrapper at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/port.c line 143

I am not really sure what this means, but I do not experience such issues when not using I2S stepper stream on a coreXY. I2S stepper stream on a cartesian also works fine, so it seems the issue is with the planner and endstop during coreXY movements.

Maybe possible problems with HAL_timers_ESP32.cpp? Seems like the HAL_timer_enable_interrupt and HAL_timer_disable_interrupt don't do anything.

/**
 * Enable timer interrupt on the timer
 * @param timer_num timer number to enable interrupts on
 */
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
  //const tTimerConfig timer = TimerConfig[timer_num];
  //timer_enable_intr(timer.group, timer.idx);
}

/**
 * Disable timer interrupt on the timer
 * @param timer_num timer number to disable interrupts on
 */
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
  //const tTimerConfig timer = TimerConfig[timer_num];
  //timer_disable_intr(timer.group, timer.idx);
}

Or possible problem with stepper.cpp? Because it says something like this:

void Stepper::stepper_pulse_phase_isr() {
...
    // TODO: need to deal with MINIMUM_STEPPER_PULSE over i2s
    #if MINIMUM_STEPPER_PULSE && DISABLED(I2S_STEPPER_STREAM)
      // Just wait for the requested pulse duration
      while (HAL_timer_get_count(PULSE_TIMER_NUM) < pulse_end) { /* nada */ }
    #endif

I don't understand Marlin's way of planning the steppers enough, so it is tough for me to debug this on my own.

vivian-ng commented 4 years ago

I managed to solve the reset issue with luc's help. See details in the separate issue here and the solution here.

@felixstorm You mentioned about the printer freezing in the middle of prints before continuing. I also experienced the same issue when I am using my board with I2S. It does not happen on my other board which does not use I2S. Basically, about 2-3 hours into a print, the printer will stop printing for a couple of minutes before continuing with the print. For long prints, this can happen several times. But the printer is still actively sending out PWM signals for heating (my heated bed and hotend continue to maintained at temperature) so I think the issue is with the I2S stepper stream, but not with the I2S in general. Maybe someone with better knowledge of the I2S stepper stream can advise...

felixstorm commented 4 years ago

@vivian-ng My experiences are about the same, only that the pauses seem to be a bit shorter IIRC (maybe 30-60 seconds).

Unfortunately I did not have any spare time to do research on this during the last months, but hopefully I'll find some time during the holiday season. Also, as I do not have as much CPP knowledge as @simon-jouet by far, I can only give it a try and maybe with a lot of luck might find a reason for the pauses...

vivian-ng commented 4 years ago

@felixstorm Are you using TMC drivers? I will be trying out a few longer prints over the next few days, using both I2S and non-I2S versions of my boards to see if it is a problem with I2S. Both will be using TMC2130 SPI mode on X and Y.

My hunch is that it could be a TMC issue, due to similar symptom here.

felixstorm commented 4 years ago

Are you using TMC drivers?

@vivian-ng Not really. I do have stepper driver modules on the PCB that use TMC drivers, but I do not use TMC support inside Marlin, so I do not think that our freeze is related to the TMC drivers.

I also watched a few prints during the last few days and did start with a tiny bit of debugging, but unfortunately I did not find anything obvious that caught my attention. My findings so far (just for reference):

If I find a bit more time, I will try to continue debugging a bit more to trace down where the delay comes from, but as I am quite busy, this might not happen anytime soon :-(

@vivian-ng, @luc-github Are both of you absolutely sure that it only happens when using I2S? This might still very well be correct, but then the problem does not seem to be directly related to the I2S code (as this continues to run just fine as listed above).

luc-github commented 4 years ago

@felixstorm I do not have a system setup actually - I just have r1 @simon-jouet's board so I never saw the issue.

vivian-ng commented 4 years ago

@vivian-ng, @luc-github Are both of you absolutely sure that it only happens when using I2S? This might still very well be correct, but then the problem does not seem to be directly related to the I2S code (as this continues to run just fine as listed above).

@felixstorm I can't say for sure, it is only a hunch. I just did a few prints over the past two days. 3 prints on non-I2S board running TMC2130 in SPI mode. Longest print was 6+ hours, no freeze. 2 prints on I2S board running A4988 and no LCD, longest print was 5+ hours, no freeze. I will try a few longer prints over the next few days to see if I get any freezes.

vivian-ng commented 4 years ago

Cross posting from here as it likely has to do with I2S stepper stream. Hopefully, this sheds some light on the babystepping issue on I2S stepper stream.

Test machine: cartesian (Ender-3) Board: MRR ESPE (ESP32 based board using I2S stepper stream) Stepper driver: TMC2130 on X and Y, A4988 on Z and E LCD: CR10 stock display

Got an error during babystepping with the following:

Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC      : 0x40089e15  PS      : 0x00060b34  A0      : 0x80174374  A1      : 0x3ffbe690  
A2      : 0x00000000  A3      : 0x3ffb8058  A4      : 0x00000001  A5      : 0x00000001  
A6      : 0x00060b21  A7      : 0x00000000  A8      : 0x3ffb8058  A9      : 0x0000abab  
A10     : 0x00000003  A11     : 0x00060b23  A12     : 0x00060b21  A13     : 0x00060921  
A14     : 0x00060721  A15     : 0x3ffbec24  SAR     : 0x00000019  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x400029ac  LEND    : 0x400029cb  LCOUNT  : 0x00000000  
Core 1 was running in ISR context:
EPC1    : 0x400d3371  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x40089e15

Backtrace: 0x40089e15:0x3ffbe690 0x40174371:0x3ffbe6b0 0x400d6e9b:0x3ffbe6e0 0x400f6fe7:0x3ffbe710 0x400e1bba:0x3ffbe730 0x400e1bdd:0x3ffbe750 0x400f7f25:0x3ffbe770 0x400f7f4b:0x3ffbe790 0x40081011:0x3ffbe7b0 0x400848a5:0x3ffbe7d0 0x400f2423:0x3ffb1cc0 0x400f0908:0x3ffb1cf0 0x400f091c:0x3ffb1d20 0x400f16ee:0x3ffb1d40 0x400e152b:0x3ffb1d70 0x400f6195:0x3ffb1d90 0x400f62fd:0x3ffb1dc0 0x400f6347:0x3ffb1e00 0x400f48a3:0x3ffb1e40 0x400f49ad:0x3ffb1eb0 0x400f4a78:0x3ffb1ef0 0x400e82f7:0x3ffb1f10 0x400e7193:0x3ffb1f30 0x400e79b1:0x3ffb1f50 0x400e9120:0x3ffb1f70 0x400e17a1:0x3ffb1f90 0x4010a469:0x3ffb1fb0 0x40088cb1:0x3ffb1fd0

Core 1 stack decode
-------------------
PC: 0x40089e15: vTaskExitCritical at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4274
EXCVADDR: 0x00000000

Decoding stack results
0x40089e15: vTaskExitCritical at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4274
0x40174371: timer_get_counter_value at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/driver/timer.c line 54
0x400d6e9b: HAL_timer_get_count(unsigned char) at Marlin/src/HAL/HAL_ESP32/timers.cpp line 147
0x400f6fe7: Stepper::babystep(AxisEnum, bool) at Marlin/src/module/stepper.cpp line 2406
0x400e1bba: Babystep::step_axis(AxisEnum) at Marlin/src/feature/babystep.cpp line 47
0x400e1bdd: Babystep::task() at Marlin/src/feature/babystep.cpp line 56
0x400f7f25: Temperature::tick() at Marlin/src/module/temperature.cpp line 2731
0x400f7f4b: tempTC_Handler() at Marlin/src/module/temperature.cpp line 2339
0x40081011: timer_isr(void*) at Marlin/src/HAL/HAL_ESP32/timers.cpp line 75
0x400f2423: ftostr54sign(float const&, char) at Marlin/src/libs/numtostr.cpp line 244
0x400f0908: _lcd_babystep(AxisEnum, char const*) at Marlin/src/lcd/menu/menu_tune.cpp line 68
0x400f091c: _lcd_babystep_z() at Marlin/src/lcd/menu/menu_tune.cpp line 102
0x400f16ee: MarlinUI::update() at Marlin/src/lcd/ultralcd.h line 487
0x400e152b: idle() at Marlin/src/Marlin.cpp line 652
0x400f6195: Planner::_buffer_steps(XYZEval  const&, float, unsigned char, float const&) at Marlin/src/module/planner.h line 567
0x400f62fd: Planner::buffer_segment(float const&, float const&, float const&, float const&, float const&, unsigned char, float const&) at Marlin/src/module/planner.cpp line 2572
0x400f6347: Planner::buffer_line(float const&, float const&, float const&, float const&, float const&, unsigned char, float) at Marlin/src/module/planner.h line 661
0x400f48a3: segmented_line_to_destination(float const&, float) at Marlin/src/module/planner.h line 692
0x400f49ad: prepare_move_to_destination_cartesian() at Marlin/src/module/motion.cpp line 853
0x400f4a78: prepare_move_to_destination() at Marlin/src/module/motion.cpp line 1033
0x400e82f7: GcodeSuite::G0_G1() at Marlin/src/gcode/motion/G0_G1.cpp line 105
0x400e7193: GcodeSuite::process_parsed_command(bool) at Marlin/src/gcode/gcode.cpp line 229
0x400e79b1: GcodeSuite::process_next_command() at Marlin/src/gcode/gcode.cpp line 882
0x400e9120: GCodeQueue::advance() at Marlin/src/gcode/queue.cpp line 645
0x400e17a1: loop() at Marlin/src/Marlin.cpp line 1137
0x4010a469: loopTask(void*) at /home/user/platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp line 19
0x40088cb1: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

Using babystepping by gcode gives the same error, minus the LCD portion of the stack.

This is likely an I2S issue since I tried gcode babystepping on the MRR ESPA (non-I2S) and it works. Just posting in case anyone has time to look at the code and try to decipher what may be wrong with the timer code.

vivian-ng commented 4 years ago

Collective minds of the ESP32+Marlin community, two questions:

  1. Why doesn't I2S stepper stream work with linear advance? When I look at the code, it seems to have something to do with ISR multi-step, but my understanding of the actual code is poor and I cannot figure out how it works (or doesn't work).
  2. Why doesn't I2S stepper stream work with baby stepping? I still cannot figure out how the timing code allows babystepping to work without I2S stepper stream, but causes a crash when I2S stepper stream is used.
felixstorm commented 4 years ago

@vivian-ng I think the problem with both is that when using I2S, the "real" stepper ISR (see https://github.com/MarlinFirmware/Marlin/blob/1955eea1b8f13697259e0e2403d47279d2d1ac6a/Marlin/src/module/stepper.cpp#L1338) never gets called but only Stepper::pulse_phase_isr() and Stepper::block_phase_isr() (see https://github.com/MarlinFirmware/Marlin/blob/1955eea1b8f13697259e0e2403d47279d2d1ac6a/Marlin/src/HAL/HAL_ESP32/i2s.cpp#L156) whenever new steps are needed to fill the I2S buffer.
One would probably have to add the logic to call advance_isr() and babystepping_isr() there, too. Unfortunately it does not seem like an easy task on first sight since one probably needs a good understanding of the stepper timings to be able to succeed :disappointed:

simon-jouet commented 3 years ago

Going to close the issue now that the R3 board is out (it will need some tweaks) and so we can start issues that are more on topic

Just to go back to the 5 months old comments above. Yeah @felixstorm is right when using the i2s stream we manually call the pulse_phase_isr just to get the timing of the next step to add to the buffer. To support linear advance we would need to do the logic there too, I haven't had a look at that code in a long time so I can't say just now how much effort it would be.

For the baby stepping it's because the way it's working in Marlin is a bit hacky, it just creates a step outside of the planner so it doesn't get scheduled on the i2s stream