PID -Hardware needed for a software fix

Both ways worked a bit, PulseIn is easier for me to understand. Falling and Rising I just had it loop and pull the current reading when I needed it.

M05 turns off the enable pin and silences the PWN pin. Good I think.

M03 /4 is erratic and backwards, lower speed cause higher pwm numbers. Re-flashing with reverse logic. I am getting odd numbers 12-1697, instead of 0-255 (or 1023). Maybe because of the reverse? Marlin takes forever to flash. Changing the nano baud rate doesn’t seem to effect the readings. I have it set to match at 250000, but lower seems to work fine.

1 Like

Ahhhh learning, that is micro seconds…see not just a pretty face.

Oh dam it is looking good now super clean I swapped my inter board Grounds and now it is looking good. 0-2012 ms with a range of about 7ms in each reading. Pretty sure it registers it all, I can see a difference of 50-100rpm command in the numbers If I run an average maybe even finer.

Pretty stoked this is getting good.

Ah, waiting with fingers crossed.

Heh, I was on page 1 when I said that. I hadn’t noticed there was another page. :slight_smile:

So close now, tomorrow is try to rig up the RPM sensor side. Either way we at least have dumb control now.

The baud rate only affects how fast characters get to the debug console. Faster would mean less time printing.

Those are microseconds, so about 2 milliseconds. You can set the timeout to be 5000 then. Do you get anything funny when it’s always on our always off? I would expect it to return zero if the pwm is set to 255, because there’s no pulse. That’s easily checked with a digitalRead. So if it returns 0, check if it’s high. If it is, then pretend it returned max.

Awesome progress though. Do you have any idea what speed you’d like to be able to run the control loop? That would include reading the sensor, and making an adjustment in the output. 10Hz is too slow. 100Hz might be too slow too. 1kHz seems too fast.

Some light reading, in case you haven’t written a PID loop in C before. It’s pretty simple, actually.

Once I cleaned up the ground issue it all worked as expected. Not sure if it was loose or dirty or the stupid breadboard. Super clean numbers.

I didn’t see any issues with 255. I had it running as I read and tried to figure other things out and it seemed to hold up fine.

I remember reading a snippit in there about the right speed. At least I hope so. Or brute force trial and error. I think the speed all comes down to the control equations right and rpm sensor, like how often the PID needs an update to work well. Thinking adaptive/tricoidal milling and all the variances that is gunna cause.

Lcd, Rpm sensor, PID equations left. All of those intimidate me but we’ll see. PID was my last actual math class, control systems. I really hope it doesn’t get that deep. There has to be some baby equations I can decipher somewhere.

Need to contact the maker and see if I can get a giant batch so we can all play with the AC triac controller thing, even cheaper.

I have high hopes this will work.

Side note Marlin 2 makes using Lasers really easy now, no more pin tweaking, and the marlin zero extruder stuff is getting pushed soon so dual endstops will be easier as well! Seems like the perfect time to be running marlin and pushing boundaries.

Dude! perfect link, I will sleep better for sure not worrying about that math.

His windup guard and zeroizer is where I figure the enable pin comes in as well as maybe a power relay…

1 Like

Oh, it will.

About timing. Is the pulse in for the input takes up to 2ms, that’s probably ok. But at 1krpm, one rotation of the collet will be 60ms. We need to stay under 10ms for 100Hz. So we will probably need to use interrupts.

Getting the interrupt on the right pin will make things a bit more complicated, but you can do the same thing as pulseIn without stopping the program.

Just interrupt on change. If it’s high, then set a “begin” variable to be the current microsecond value, and if it’s low, then subtract “begin” from the current microsecond value and set a global (and volatile) variable with that value. In your code, you can then check this global value in your loop. It’s probably shorter than this paragraph :slight_smile:

PulseIn is going to be fine for a first draft, but as soon as you’re to the stage of tuning the PID, we should probably switch. Having a slow loop will make the PID harder. Plus, it’s silly to have the CPU just waiting for the router to turn. We will have plenty of headroom if we use the interrupts.

For the sensor, you will probably just want to look for a rising edge, and just subtract the previous time you saw a rising edge.

I thought the raising a falling thing was out side of the control loop and did similar things as the interrupt version? Either way, should be no big deal right now. From what I saw last night was the nano has 2 capable pins pins and I am already on 1 of them just to be safe in case this came up. Other boards have more.

Using the rising thing was cool with a serial.print (of course it wouldn’t normally be there) because you could see all the readings going by and every once and a while you would see the control loop spit out its numbers. Cool basic debugging.

I am kind assuming the rpm sensor and the PWM input with both need to be on separate interrupt type loops and the control loop will just check them as often as it can ( I have no idea)? I understand the basics of the interrupt stuff but have never used it, can’t wait to learn. The signals seem very similar, it is just looking for how often a high signal is detected.

Your insight is invaluable…I am sure you have had very similar things to deal with before.

I’m not sure what the rising falling thing is. There are many ways to skin this cat, for sure. The benefit of doing the timing in a quick ISR is that it won’t be bothered by timing in the control loop and it won’t be bothering the speed of the control loop. If you have the ISRs measuring the plus width of the input and the period of the rpm sensor, then the main loop can just capture those values at the beginning, compute and set the output, even print status to serial, and then wait (sleeping or polling) until it’s reached it’s desired frequency.

I haven’t done this in Arduino before. So some of this advice might be terrible ;). I have done PID loops in C++ in real time operating systems and in Linux before. I definitely don’t want to dictate the solution. It will be better for you if you’re the one who does that. Then you won’t have trouble fixing it.

Trying it out now, get the inturupts working now while it is simple. Trying to do the right thing and get byte, sort, int put in correctly. Slightly foreign to me but arduino is well documented.

I got it from here. Each time I read this stuff I understand it a bit more. http://www.benripley.com/diy/arduino/three-ways-to-read-a-pwm-signal-with-arduino/

1 Like

Yep, that’s a good write up.

I tried HIGH, and Change. Both worked but just slowed it down to a crawl updated the values once a minute maybe.

[attachment file=52851]

So then I tried the other thing and it seems to work well. See anything fishy or a reason to go one way over the other?

[attachment file=“52852”]

The PWM In number is stable to ±2 now and the range is from 0-2024. With the range set in marlin up to 30k a change of 100 rpms seems to show in the output, the math says 0-255 should be about 117 between steps so pretty good right?

 

Very good. Using pulseIn in the interrupt routine won’t work. The rising falling is perfect.

For the rpm reading, you can just do a (separate) rising function, and compute the difference between rising edges.

int now = microseconds;
rpm_value = now - prev_rpm;
prev_rpm = now:

I had to take a break, Al sent me a lit acrylic sign, pretty fun.

I have my electronics goody box out and I have two kinds of uv led sets I can try for the RPM thing. I am going to get that running on a separate nano for now, just to try and read the RPM. Then get them on the same board.

Good to hear about the other code. So using the other interrupt, is on it’s own “circuit/channel” I guess you would call it. So each interrupt runs independently of each other and the main loop?