Gas station without pumps

2017 November 15

Progress report on mechatronics

Filed under: Robotics — gasstationwithoutpumps @ 19:27
Tags: , ,

I’m falling behind in the mechatronics course—I still don’t have a complete design for the robot, and I’ve built nothing so far except the cat-toy ball track, which is not complete yet—I need to know how much of it to cut away for the ball launcher(s), which I’ve not designed.  I also have the digital beacon detector done, though I think I want to retweak the code for it, as I messed it up trying to get more sensitivity at the distance competition.

I spent yesterday struggling with SolidWorks.  I’m getting better at it, but it is still a terribly complicated, unintuitive interface.  Even trivial things like creating a sphere as a model ping-pong ball took a long time to figure out (I had to Google it, and even then it took me a long time to realize that “centerline” was a special tool, not just a line through the center.  My biggest accomplishment in SolidWorks so far is modeling the helical cat-toy ball track—I’ll have to get a picture of that model to put on the blog.

I did get most of the first layer of MDF designed yesterday, with the motor mounts, the wheel wells, the tape-sensor holes, the battery holder (MDF and velcro), and the M10 ball-tip set screws (to use as skids) all modeled.  I even got one support board for positioning the next layer done, though I’ll probably have to adjust it a bit, as I changed my mind last night about what bumper switches to get.  Instead of spending $3–5 a switch for gold contacts (which is the “right” way to handle low-current switching), I followed the lead of one of the students and am getting super cheap switches from Amazon, which are $7 for 10 switches.  These are standard 5A switches and probably get unreliable with currents below 100mA, though I’ll be using them with 1mA or less.  They are also tiny (specs from the Amazon page):

  • Overall Size : 20 x 6.5 x 13.5mm / 0.79″ x 0.26″ x 0.53″ (L*W*H)
  • Mounting Hole Dia. : 2mm / 0.08″;Mounting Hole Spacing : 9.5mm / 0.37″;Pin Pitch : 7.2 x 9mm / 0.28″ x 0.35″
  • Lever Arm Size : 17.5 x 4mm / 0.69″ x 0.16″ (L*W);Roller Size : 5 x 3mm / 0.2″ x 0.12″ (D*T)

The small size means that the second level will have to be slightly higher to put the bumpers at the right height.

Before I cut the first-layer board, I want to add the rest of the spacer boards between the first and second layer—one of which will have my volt/ammeter and power barrel jack (so I need to measure those and design the panel for them).

I also have to decide how I’m going to lock the boards together.  I don’t want to glue things (messy and hard to disassemble), so I’ll probably clamp everything together with threaded rods.  I’ll need to get the threaded rods and figure out where to put the holes for them so as not to interfere on any level—avoiding the cat-toy ball track will be the hardest, as it takes up most of the second level. Although most of my robot will be using metric parts, I’ll probably go with threaded rod from the hardware store, which will most likely be ¼” rods with 20 threads per inch, as that seems to be the cheapest (at 50¢–$1 a foot).  I think I’ll need 4 pieces, a little under 11″ long each (so that the top of the rod is at 11″ but the bottom doesn’t touch the floor).

I need to laser cut a small test piece with different hole sizes, to see how much increase in diameter there is from the laser cutting.  Most of my holes can be a little loose without problems, but the set screws need to screw into the MDF (unless I get some M10 nuts and put them on either side of the MDF, which might be a better solution anyway).

Today I was going to build tape sensors (soldering the TCRT5000 reflective sensors and current-limiting resistor onto protoboards that have screw holes drilled for mounting), but I’ve not done any hardware work so far today.  Last night I did order the bigger (100mH) inductors for the track-wire sensor, plus a few smaller shielded inductors, in case I decide to add another LC resonator to the sensor, to increase noise rejection, but I forgot to order an 8:1 analog mux, which I think I’ll need for extending the number of pins on the Teensy.  Oh well, another $3–4 in shipping costs and another few days delay.

I’ve spent most of today working on porting the Events and Services Framework to the Teensyduino environment.  I’ve got it all compiling and I’ve got event checkers working, but I haven’t checked the timers or other layers of services.  It turns out that the test harnesses built into the code have not been maintained, and some wouldn’t run (or even compile) even on the Uno32, because the code they supposedly test has been changed and no longer has the entry points they rely on (ES_Timers is one example).

The ES_Framework code is also not very modular, despite being broken up into many files—almost everything is intertwined to the point where you need it all before anything can compile.  Luckily, most of it has very little dependence on the specific processor, so I was able to port it without trouble.  One of the biggest problems was that the Teensyduino environment does not support printf, and the Serial.print() routine is C++, not C.  I added a few C wrappers for different flavors of Serial.print() and converted all the printf statements to a series of Serial_print_… calls.

I’ve not still figured out the best way to handle the analog-to-digital conversion.  The Pic32 processor used in the Uno32 boards for the class have a “scan” mode where the hardware handles scanning the selected analog channels, just doing an interrupt after all the channels have been scanned.  The Kinetis processors on the Teensy boards do not have that feature, so I have several options:

  • doing conversions in event detectors or services that need the values.  This will make the individual detectors slower, but no time will be wasted doing unused conversions. It would also make it easy for users to extend the number of analog pins with an external MUX, as the code for doing the analog conversions is not buried inside the system, but in the user-level code.  The disadvantage is that the code will need to busy-wait for each conversion, as the result is needed at the point in the code where it is requested.  I could just use the Teensyduino analogRead(), which already provides support for setting the resolution and averaging levels.  Then there is no need to port the AD.c file.
  • do a block of conversions just before calling all the user-defined event detectors.  This will put a largish delay before the event detectors, but several detectors or services can look at the value with needing another conversion. Currently, the event detector loop with just a trivial DummyEventChecker (that reports an event every 100,000 calls and toggles the on-board LED) takes about 3.34µs on a 72MHz Teensy 3.1, but doing 6–8 conversions would add 8–500µs, depending on how much hardware averaging I decide to do (which the user should be given access to control).  This technique is probably the closest to letting me duplicate the existing interface, which is designed around the Pic32 scan.
  • do a start-conversion and interrupt for each conversion.  If I do little hardware averaging, the overhead of the interrupt processing is large and nothing is gained, but if I opt for 32× averaging then interrupts have a big advantage over blocking code that busy waits for the conversions.

Currently, I’m leaning towards just using the analogRead() code, discarding all the Pic32-specific AD code.  I still need to decide whether to build in a battery-level check that shuts down the system on a drained battery.  Perhaps the cleanest way to do this would be to build a separate event checker that samples the battery voltage about every millisecond and low-pass filters it (rather than at 9345Hz/number of pins, the way the Uno32 code does).  (Sampling about every millisecond could be done just by watching the clock in the event checker and taking a new sample every time that millis() changed.)  Having a separate checker in a separate file, rather than intertwined with BOARD.c, AD.c , and roach.c would be much cleaner. After I’ve gotten all the basic functions working, I’ll think about dedicating a pin (perhaps A0, which has the fewest other functions) to battery-voltage monitoring.

I’m not sure how to ensure that all the external devices (servo motors, gear motors, … ) are properly turned off in BOARD_End(), before sleeping or halting the processor.  The Uno32 version of BOARD_End() doesn’t seem to do this either—in fact, it keeps the ADC and the serial port on, and just turns off most interrupts and sets pins to be digital inputs, not doing anything about the external peripherals that are the power-hungry ones.

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: