Closed ryancoe closed 3 years ago
@DeepFriedDerp thought this link might be helpful: http://sphinx.mythic-beasts.com/~markt/ATmega-timers.html
@ryancoe thanks for the reference @nickross4444 I couldn't figure out from the diagram (and honestly can't recall from last week) if you are using the MEGA or the Due for driving the stepper motor. Could you or @ryancoe or @delaneyheileman advise on that?
The reason I ask is that there is a lot of readily available library source code and examples for AVR timer/counters, not so much for the SAM3x8e (Due), and the ARM source code (located in that hidden labyrinth that is AppData\Local\Arduino15) contains a mostly empty header file (tone.h) and a disabled copy of the AVR-specific tone.cpp source file. I did fine a list of reference macros related to the SAM3x Timer/counter settings that may be useful if we do end up having to try to reconfigure clock dividers and whatnot.
@DeepFriedDerp The stepper is driven off of the Mega
@nickross4444 - Please use this spreadsheet to figure out what we need. Note that I currently have the wave amplitude set of 5 cm and wave frequency of ~4 Hz -- I think these are reasonable, but they are not must-have requirements. Also note that the lead screw pitch and belt gear ratio should be updated; please note those numbers in this Issue thread as well. miniWaveTank.xlsx
AccelStepper
: f < 4000 Hz
Tone
: 31 < f < 65000 Hz
One idea would be to use something like this: https://www.sparkfun.com/products/11420 (would also need a transistor or level-shifter like those used for the encoder #14).
@ryancoe It looks like we can solder over a jumper on that board to enable 5v operation. Looks good to me.
As an alternative path, I have managed to get one of the Timer3 channels to output a square wave the same way as the tone library, but with a range of 1Hz to 31.25kHz, with a resolution of about 1Hz.
As long as we have a free Timer Compare channel on either Timer3, Timer4, or Timer5, where me messing around with the clock prescalers won't break anything else that you are using, then I should be able to get this code up and running in time to serve as a backup to the signal generator shield.
From my previous spreadsheet (which should be updated with latest gearings before drawing conclusions), we needed f < 29 kHz, so this Timer3
approach may be viable.
With our new gear ratios(though I suspect the pitch might be incorrect) I came up with about 15kHz as a max frequency. Timer 4 and 5 are used by our interrupts on the mega, but timer 3 should be completely free. With all that in mind, @DeepFriedDerp 's code should be more than sufficient, assuming it is able to run with all the other processes. I would think it'd be fine, since tone() hasn't interfered with anything.
To be clear, you're proposing using the Timer3
channel and some code that @DeepFriedDerp has written to create the signal through this?
@ryancoe That or using the signal generator, either should work fine.
Ok, I'm ambivalent (because I don't really have the expertise to judge these options). I'm happy with whichever path you prefer.
So I've drafted up and tested the code, and its absolute upper limit is about 15.6kHz. I think the limit here may be due to me loading up the mega with several interrupt functions in order to test the code, which may also be a problem with the MEGA on the SIWEED, unless the Timer4 and Timer5 functions are not happened at a very high frequency. @nickross4444 may be able to comment on the current state of the interrupts.
I've also checked the execution time of some of the setup functions necessary to switch tone frequencies and durations. It looks like the slowest function executes in 60 microseconds, with maybe a few additional clock cycles for all of the bit registers to write and sync.
Since this function, as set up on my MEGA, lacks a 1-to-1 relationship between the expected frequency output and the measured output, given a particular frequency setting, it will probably require some calibration. Given this and the fact that the current maximum frequency is very close to the maximum required frequency for adequate operation, it may be a good idea to purchase the dedicated signal generator breakout, just in case this code does not live up to hype during testing on the actual system. @ryancoe what are your thoughts on this?
Once I document the code, I'll post it to a feature branch and generate a pull request so that the merge operation is contingent on successful unit testing. This code is not in a library format like before, because the timer-compare interrupt vector macros absolutely do not play well outside of a .ino sketch for some reason. I know that tone.cpp got it to work, but I do not have those particular magical powers that it's author obviously has. So in this case, it will require a series of global variables near the top of the main sketch, and some functions down at the bottom of the main sketch. I would have hoped to have avoided this messy implementation...but it works.
Let me know if you have any questions or comments.
The interrupts in their current state do take a decent chunk of processing time, so if we were to use this a dedicated Arduino would probably be the way to go(with this solution). If we're going to use another board anyways, it makes the most sense just to go with the dedicated hardware.
In that case, I tend to agree that the best solution would be a dedicated IC breakout for signal generation. Looking over the datasheet for the waveform generator, it has 28-bit frequency resolution, which works out to ~0.01Hz of resolution up to 3MHz
@ryancoe, should I take an action to purchase a few of these? They are available on Digikey, so we can purchase them with a JIT order. Digikey Link to BOB-11420
@DeepFriedDerp - Yes, please get ~5 of these boards and anything else you need for this arrangement.
5x BOB-11420's and associated headers have been purchased. I'll update when they arrive on-site.
Good news, I believe that The bob-11420's will work. See below for pics, but I was able to generate easily 4hz-20khz. (and higher, but I believe it was said this was the range needed). Below 10hz the waveform looks a bit weird, but I believe that's because of my lack of oscilloscope skills? What I need to do now is to see if I can integrate this into the wave generator code and get it to work from there.
@SeanPluemer very nice. I think that's probably slop in the signal generator, but it should work just fine for stepping.
Update for this issue: We tried running the servo from the signal generator, everything worked great in the higher Hz. But below 20Hz the servo was still acting jittery. We believe this is because the motor controller appears to be picky about the wave being sent in. As mentioned before, that at low Hz the signal generator does output was not a perfect square wave.
To get around this, Nick pulled a genius move and simply added a MOSFET, triggered by the signal generator. With this, the servo appears to be working perfectly now. All that is left is the software implementation.
The methods/library we're using to control the stepper motor for the wave maker allows fast motion, but cannot work below a certain limit (2.6 mm/s with our current gearing). This can create jittery behavior, especially in jog mode.
@nickross4444 - Rewrite this if I've misunderstood the problem or left things out