Closed plpers closed 3 months ago
Interestingly, I can get 4 steppers to work but only with blocking move() commands. Any thoughts if I am exceeding a queue length, or similar, that I need to be mindful of when using the stepperengine?
It would be of help, if example code can be shared, which illustrates the problem. Based on the problem description, I have no clue, what is going on. Besides, stop working means what exactly?
Sorry, not the best bugreport in the world :) Here is some code to take a peek at. Sorry about all the chickenscratch about as I was just getting a feel for the problem before I get out the Jlink. main_Issue 243.zip
Per how I programmed the device, I expect a good output to look like this: Good_Pulse_Output.zip Unless otherwise noted, I generally get good outputs. However, some pins magically don't work, and as I start to add more pins, I start to see problems.
Pertinent lines where pin assignment doesn't work are in 24-38. I have them listed below for reference:
See Poor Pulse Output for if I change to 51. Poor_Pulse_Output.zip
If I add two more steppers, I get weird behavior again: main_Issue 243_6Stepper.zip
Also- for main Issue243.cpp, the 4 stepper file - I just tried to download myself the zip file to reproduce - and now the issue creating an EN-Like signal isn't there. Something is really weird.
I'll try to dig into it a little more with Jlink first. However the 6stepper file is reproducible. Also I just tried to add a 5th stepper to the 4 stepper file and I got the same "poor pulse output" behavior as before. I corrected an error where i was assigning the same pin twice, and no dice. I cant seem to get above 4 stepper motors somehow....
I have had a look at the main issue 243 6stepper.zip file.
Findings:
Thanks for the reply. A couple questions:
spi is not used for digital pins. I am attempting to use the HSPI bus. Per https://docs.espressif.com/projects/esp-idf/en/v3.3.6/api-reference/peripherals/spi_master.html that is
or perhaps I am mistaken? my understanding is that VSPI and HSPI are available for applications, SPI0 and SPI1 are for the ESP's flash use. SPI is working ok as far as I can tell.
setExternalPin() only strips bit 7 (external pin flag) and uses this as pin number got it. So In other words, I need to use pin numbers > 170 (170 = 128+ 42, the highest ESP numbered pin per your link) is that correct? In syntax this could be written as setEnablePin(43 | PIN_EXTERNAL_FLAG).
please check possible esp32 pinning. as per that document, pin numbers higher than 33 cannot be used. which esp32 variant/board do you use? I use the ESP32 Devkit V1, which has pins exposed up to 35.
you enable Serial, so pin 1 is not available. Just to confirm: does this mean a pin definition of 129 will collide with GPIO1? it seems in the example from the repo then, setExternalPin(pin, value) if you set a pin to 129, will result in pinMode(1, OUTPUT). Is that correct?
if setExternalPin() is called every 4ms, then the call does not return the expected value and the stepper task tries on each cycle again and again. Ah I see. read too fast. I added a register that acts as a dummy for now. I got it working up through stepper 6, but then i had to skip some pin numbers to make it work. The ESP appears to be crashing if I add more than 6 steppers. See semiworking.txt. semi_working.txt
in setExternalPin()
a constant value is set: spiCommand(hspi, 0b01010101);
. Apparently the shift register has nothing to do with any pin value.
The PIN_EXTERNAL_FLAG
aka bit 7 marks a pin value to be external. The valid range is then 0…127. There is no relation anymore to the valid pin range.
The pin collision using value 1 is happening, because the current setExternalPin()
uses this value and then sets the esp32 pin.
My expectation would be a routine like:
uint16_t spi_pins=0; // current value of the shift register
bool setExternalPin(uint8_t pin, uint8_t value) {
uint8_t spi_pin = pin & ~EXTERNAL_FLAG;
if (spi_pin >= 16) return !value; // error case
uint16_t pin_flag = 1<<spi_pin;
spi_pins |= pin_flag;
if (!value) {
spi_pins ^= pin_flag;
}
spiCommand(hspi, spi_pins);
// assume spiCommand never fails and sets the pin successfully
return value;;
}
recommendation is, to first check, that the setExternalPin()
is working as expected - without any stepper or FastAccelStepper. Only the shiftregister and a measurement device (or LED connected).
the shift register i'll tighten up - i have not been using a stepper motor, only checking that step pulses are good. I decided to write the fake spi transfer just to check if the esp32 was getting bogged down with tasks or not. (I realize the spi transfer does nothing, sorry for the confusion)
I'll try and clarify the remaining issues when i am back (currently traveling)
Hi @gin66 thanks for looking at the code. The main problem was that i referenced a bad array and I am frankly not sure how it worked at all. I discovered it once i got out the jlink and lo and behold the numbers in my pinArray that held external register state were optimized out by the compiler and not watchable :)
Now it's working just fine after a really dumb mistake. Once again, thanks for a great library. I am closing as not a defect.
I do have a question, however: it appears from bench testing that the queue depth is shared among all steppers. Is this true? What I observe is if I have a stripped mainloop like this
void loop() {
stepper1->move(100);
stepper1->move(-100;
stepper2->move(100);
stepper2->move(-100);
stepper3->move(100);
stepper3->move(-100);
}
stepper3 will eventually stop getting pulses. you can see how on the oscilloscope stepper 1 starts hogging all the CPU time eventually. If I move to 100000 steps they all share nicely, and all steppers up to 12 keep moving.
If so, is there a way to confirm if a move() command successfully got into queue or not? I believe a lot of the issues I saw once I corrected my code are around overwhelming the queue (assuming it is shared) this way I could write a repeat routine to attempt to re-add the command to queue.
Not a defect, developer implementation error
I have a project where I'd like to control 12 stepper motors with one ESP32. When writing the prototype, I found that assigning EN and DIR to shift register output, for some reason when I create virtual pins higher than 134, the library stops working. So as a result, I can create Enable pins like
define Stepper1EnablePin 1
define Stepper1DirPin 2
define Stepper2EnablePin 3
define Stepper2DirPin 4
and everything works great, using the example code including adding a callback to SPI to send some info to update pins in the required callback. when called the bitwise OR converts say Stepper1 Enable Pin to 129, Dir to 130, and so on.
However when adding more *stepper3 using the factory method, and using
define Stepper3EnablePin 5... converting using the bitwise OR to convert to 134, etc the library stops working.
I am using Version 3.11 on platformio. Any thoughts why this might be happening?