It’s Alive!
With the electronics and mechanics of Scribble done, it’s time for the first tests.
Scribble is a very complex machine, and it’s pushing some of my skills to the limit. While I’m confident it will work, I’m also realistic enough to know it probably won’t work right. How do I know that? Simple.
Rule One of engineering: nothing works right the first time around.
Even if everything appears to be in order, there’s usually something that can be made better. Either that or you’re sitting on a ticking time bomb of catastrophic failure. Better to set it off now than after you hit a point of no return.
After a bit of thought, I decided that this particular test would focus solely on the mechanics. Software is complicated, so I’ll test the hardware using manual input first. Testing still requires some software since Scribble can’t do anything without the CPU directing it. Only the bare minimum is implemented here.
I can happily reveal that Scribble does in fact work. Scribble doesn’t work well– there are many obvious flaws and improvements- but it works well enough to continue on to the more interesting parts of it’s development.
Part of the Scribble Pen Plotter Series:
- Scribble Pen Plotter: The Mechanical Parts
- Scribble Pen Plotter: The Electronic Parts
- Scribble Pen Plotter: The First Functional Tests
- Scribble Pen Plotter: The Serial I/O Driver
- Scribble Pen Plotter: Rebuilding The Carriage
Initial Hardware Fixups
Prior to making things move, there are a few issues related to the hardware that need to be buttoned up prior to the actual test. Nothing major, just a few tweaks. I figure that there isn’t going to be much imagery for this article so I’ll go over them to break up all the text.
Erratic Y Feed
When I tried to move paper across the platen, it never fed properly. No matter what I did, it always slipped around. Eventually I found the heat shrink tires were not properly fitted.
Removing the tires helped a little bit, but the roller was still only making contact on one side. Further investigation showed that the shaft itself is bent. I can’t replace it just yet, so I put some shims under the platen supports. Works okay for now.
Without tires, the paper is prone to slipping. Keeping the pen pressure light helps. I have a few ideas how to make this better, though I’ll have to wait for supplies.
Wobbly Pen Holder
My pen holder is designed to slide out to change pens. When it’s pressed against the paper, the pen inevitably works free. I considered a lot of very elaborate mechanisms to hold the pen steady.
Then I just did this:
Note also that the part prominently marked REMOVE has not yet been removed.
Paper clips are a highly underrated part of your toolkit.
What Currently Passes For a Pen Change Mechanism
The pen carousel continues to taunt me with being almost a functional idea. I went ahead and installed the motor despite not having a functional carousel yet. This is because there are certain mechanical clearance issues that need to be considered before moving forward on the carousel.
While this is still workable, I’m cutting things way too close.
You can see the basic concept of how a pen change is accomplished here, along with some of the obvious problems.
Vertically speaking, I’m still figuring out the proper height. I’m probably going to have to replace this mounting bracket entirely.
Putting the Y motor next to the pen carousel was clearly a mistake. I may try to shift the motor downwards using gears or a belt.
Excessive Pen Pressure
My lifting mechanism consists of a solenoid pulling up on a hinged platform. This is a design mistake- it has long since occurred to me that the solenoid should lower the pen- but I’m sticking with it for now.
Unfortunately the solenoid spring pushes down really hard. So hard that the paper won’t move properly. I tried a few ways to make solenoid lower the pen, but the problem then became a spring that was too weak– it can’t lift the pen platform on it’s own.
Eventually I realized I could just remove the spring entirely.
One of those “I can’t believe how long it took to figure this out moments”.
This arrangement allows the pen to “float” over the paper under it’s own weight. Pens are no longer crushed into the platen. Well, not as much anyways. I really wish this idea occurred to me earlier!
Scribble Test Software
Good news: without the complex instruction interpreter, Scribble doesn’t actually need much code to get up and running.
Bad news: even simple software is hella complicated. Scribble has a few subtle traps that will trip up the unwary.
All in all, this is surprisingly little software for just how much it technically accomplishes.
Tick Timer
Stepper motors can only operate at a particular range of speeds. Calculations show that my particular motors will operate up to 500Hz or so.
Switches of any kind require sampling and debouncing. Failure to do this will result in erratic behavior. Typical sample rates are 50Hz to 100Hz.
Both of these can be handled by the same timer event. I’m using timer 0 because timers 1 and 2 are used for PWM.
//Set up TIMER 0 to interrupt at 500Hz
//CPU clock 8MHz
TCCR0B = 0x03;
TIMSK0 = 0x02;
OCR0A = TIMER_DIV;
ISR(TIMER0_COMPA_vect){
panelSwitch(); //Sample panel switches
nextStep(); //Output one step
}
Timer 0 is only 8 bits, which might cause some trouble with finding the right speed. If I really need to, I can use a software timer on top to slow down the motors. This will be required if I ever support variable motor speed.
Reading the Front Panel Buttons
There are a whopping sixteen buttons on Scribble’s front panel. I had to resort to using 74HC165 shift registers to get them all in. These are SPI compatible; I have successfully used the ‘165 with the ATmega SPI hardware before.
ATmega328’s put their SPI hardware on PORT B though, which is occupied with motor control. But, SPI is a simple synchronous protocol that lends itself well to bit-banging. As long as you have a few GPIO pins, you can put a (slow) SPI port anywhere.
//Software driven SPI port
void panelSwitch(){
static int16_t buffIndex; //This should remain persistent
int16_t newDat = 0; //Make sure this is zero every time
//Latch the input registers, putting them into shift mode
PORTC |= SW_LATCH;
//Bitbang 16 bits of data into newDat
for(int16_t i=0;i<16;i++){
if((PINC & SW_DAT) > 0){newDat |= (0x0001 << i);}
PORTC |= SW_CLK;
PORTC &= (~SW_CLK);
}
//Unlatch registers, putting them back to parallel mode
PORTC &= (~SW_LATCH);
//Add newDat to circular array
buttonSample[buffIndex] = newDat;
buffIndex++;
if(buffIndex>=DB_LENGTH){buffIndex = 0;} //Wrap around
//Calculate valid switches using an iterative AND algorithm
switchRaw |= 0xFFFF;
for(int i=0;i<DB_LENGTH;i++){
switchRaw &= buttonSample[i];
}
}
Took me a few attempts to squish out a persistent off-by-one error. A decent simulator is worth everything you have. This code definitely works, and I don’t really see a better way of doing it.
Raw key data is shoved into an 8 deep circular array. All entries are AND-ed together to get a bounce free result. See the basic algorithm discussed here. Using the 500Hz nominal tick frequency, the switches get sampled every 16ms (16.2Hz). If anything, that’s way too slow. I could probably get way with two samples at that speed.
What the buttons do is something else entirely, and will be discussed later.
Moving the Motors
To spin a stepper motor, the windings must be switched in a specific sequence. For two-phase motors it’s a two-phase square wave signal at 90 degrees phase. Rather than try to calculate this directly, I just use an index into a lookup table.
Steps are signaled by passing a byte that’s either positive, negative, or neutral. I prefer this because it integrates a little better with discrete algorithms.
/*==========
Motor output works like this:
Forwards -->
0x00,0x01,0x03,0x02,0x00,0x01,0x03,0x02
<-- Backwards
==========*/
//Easier to use a lookup table here than calculate directly
static int8_t stepTab[] = {0x00,0x01,0x03,0x02};
//Output one step, using step struct to pass values
void nextStep(){
static int8_t xPhase, yPhase, zPhase;
//Adjust the motor phase according to the step struct
if(step.xStep>0){xPhase++; if(xPhase>3){xPhase=0; step.xStep = 0;}}
if(step.yStep>0){yPhase++; if(yPhase>3){yPhase=0; step.yStep = 0;}}
if(step.zStep>0){zPhase++; if(zPhase>3){zPhase=0; step.zStep = 0;}}
if(step.xStep<0){xPhase--; if(xPhase<0){xPhase=3; step.xStep = 0;}}
if(step.yStep<0){yPhase--; if(yPhase<0){yPhase=3; step.yStep = 0;}}
if(step.zStep<0){zPhase--; if(zPhase<0){zPhase=3; step.zStep = 0;}}
//Combine the motor output into one byte
PORTD = (stepTab[xPhase]<<6)|(stepTab[yPhase]<<4)|(stepTab[zPhase]<<2);
//Solenoids are on a different port, so handle them separately
if(step.solPwrP > 0){PORTB |= 0b00000100;}
else{PORTB &= (~0b00000100);}
}
Synchronizing the motors to the program that actually calculates the steps is tricky. I chose to implement a structure that holds the various output variables in one place. A little bit clumsy, but it works just fine. I plan to extend this into a short queue to maximize throughput; having all the steps as a single struct really helps with that.
Glue Logic
Pushing one of the buttons doesn’t mean anything by itself. Each button must be assigned some operation. None of the switches are “special” in any way, so I can assign them any function. For now, at least, I chose only to implement continuous motion.
//Just check each switch bit and set the appropriate things in the step struct
if(switchRaw&BTN_XDN){step.xStep = -1;}
if(switchRaw&BTN_XUP){step.xStep = 1;}
if(switchRaw&BTN_YDN){step.yStep = -1;}
if(switchRaw&BTN_YUP){step.yStep = 1;}
if(switchRaw&BTN_ZDN){step.zStep = -1;}
if(switchRaw&BTN_ZUP){step.zStep = 1;}
if(switchRaw&BTN_PUP){step.solPwrP =1;}
if(switchRaw&BTN_PDN){step.solPwrP =0;}
Cheap, lazy, but it does the job. Each button simply spins it’s associated motor around at maximum speed. Except the solenoid buttons, they raise or lower the pen.
Lots of little things were omitted for clarity. There’s little point in showing the boilerplate #include statements, for example. Perhaps I’ll upload a complete copy of the final program, though that will be quite some time from now.
Scribble Pen Plotter Testing
I didn’t actually do any testing beyond a simple continuity test before now. While I was reasonably confident that things would be okay… well I’ve had previous experiences. Bad ones. Since I can’t put things off any longer, I plugged Scribble in and flipped the switch.
Scribble, being sufficiently unexploded, passed the power up test.
Having confirmed Scribble could power up, I started writing the test software shown above. Quite a few issues were discovered. Mostly pertaining to the fact I haven’t touched C or the ATmega in several months. When I say 6502 assembly requires you to unlearn good programming, I mean it!
Incompetence (mostly) sorted out, the remaining problems are mostly due to physical things I didn’t catch during the previous two articles. In no particular order:
Nav Switch Troubles
Probing of the panel serial output showed that the navigation switch just didn’t work. Only a couple of positions worked, and one required two directions being on simultaneously. Clearly the switch was installed incorrectly.
Turns out it was a PCB layout error. I had to make a custom footprint, and ended up doing it backwards. If I could rotate the switch 180 degrees, it would work properly. Unfortunately this switch proved very difficult to remove.
Pulling on the top of the nav switch pulled the whole damn thing apart. No way to put it back together, and no way to remove it without cutting it up.
I had a backup switch, but wouldn’t you know it, it’s broken too. Broke a long time before this one did- pin snapped off. Buying a new one would be an option- except Adafruit is currently out of stock. Digikey has a few possibilities, but none that are pin compatible.
While a significant loss, the navigation switch is not strictly necessary to keep working on Scribble. I’ll replace the switch when I can.
Inconsistent Switch Positions
When I assigned the front panel switches, I assumed they were laid out in a simple linear order. Then I started pushing them, and the results just didn’t make sense.
Chalk this one up to a combination of not making clear documentation and rotating the panel. Originally I had the pen select buttons along the bottom. Rotating them to the left side puts the lowest numbered switch in the top left, going down the column, and zigzagging through the other column. My switch reading algorithm also flips the endianess of the switch bits.
Since the button functions are completely arbitrary, this is more of an annoyance than anything else. If I’ve learned something, it’s that I should put these kinds of labels on the pcb itself. Self-documenting hardware is the best kind!
X-Axis Bearings
I was never happy with how the X-Axis worked. This was going to be a problem spot, though I’m not entirely sure I expected this kind of problem.
When I try to move the X carriage under motor control, it binds and stutters and makes quite the racket. Except when it doesn’t. Yes, this is one of those problems. Occasionally it Just Works, with butter smooth movement. Giving the carriage a little tap is enough to get it smooth. Movement spontaneously switches between smooth and stutter with no warning or provocation.
Clearly the bearings aren’t quite right. This test has shown the guide rods are definitely bent, though I don’t really know how this affects the X carriage. Twisting the rods helps except when it doesn’t. Loosening the mounting blocks helps, except when it doesn’t. Tweaking the bearings helped… you get the idea.
I suspect I will have to completely replace the bearings. They were a failed design to begin with. Since they are physically built into the carriage, I will likely have to build a new carriage.
In the meantime, slowing the motors down helps. If you didn’t know, motors are constant power machines. You can have torque or speed, but not both. Dropping speed increases torque. Torque helps power through sticky bearings. Speed is less of an issue, at least for now.
Sticky Pen Motion
Removing the solenoid spring was a brilliant solution to a tricky problem. It would remain a brilliant solution were it not for the solenoid’s pesky tendency to jam in the up position. I just can’t get a break here, can I?
Powering the solenoid “dry” shows that it’s the solenoid that’s the issue here. I don’t know why it jams; only that it does. Perhaps I should accelerate my plans to replace it with a custom one.
In the meantime I discovered that rotating the plunger seems to fix everything. No explanation why. It just does.
As expected of a complex machine, Scribble’s first run is far from smooth. Literally in some cases. The good news is this stuff mostly falls into the “annoying but manageable” category. I can make Scribble perform the basic operations of a plotter, which is more success than some projects I’ve worked on.
Scribble’s Big Debut
Now that I can actually make Scribble do stuff, I can actually show it off properly. Well, sort of. Scribble does not yet have any intelligence driving it, so we’ll have to tolerate my clumsy attempts to draw simple shapes. It’s really hard when you can’t see pen properly. Doubly so when you keep forgetting which button does what.
Video is clearly the only way I can do this, and I even have a Youtube channel dedicated to exactly this kind of thing. Don’t expect too much; I don’t really have good film equipment. Also, I may have lost all my good SD cards. I’m lucky to get even two minutes of video.
A nice full shot of various test marks. It’s hard to draw anything when your controls are so limited, but it’s easy to see that Scribble can in fact draw.
Since the Y feed is misbehaving, I chose to draw on some cardboard rather than ordinary paper- thicker sheets feed easier. It’s the kind of cardboard that has a smooth laminated surface on one side. Even then I still had slipping trouble. I ended up running a gluestick down each side. That “fixed” things good enough to shoot the demo video. Not a long-term solution.
I’m having quite a lot of trouble with the front panel buttons. Beyond simply forgetting which button does what (entirely my own fault), there’s a lot of “cross feed” between certain buttons. You’ll see I drew diagonal lines towards the top left when I clearly didn’t intend to. I’m pretty sure this isn’t a result of electrical issues as much as it is mechanical ones. Snugging up the mounting screws helps- until the buttons get stuck on. I’ll have to tweak the panel some more.
What’s Next?
It feels good to get a project working. Scribble has been a fancy paperweight for a couple of years. All that time, all that work, all that wondering if this would be yet another dead project. Scribble lives, and I am excited to push it further.
The way I see it, Scribble has three different things that need to be done prior to the grand finale:
- Fix the hardware bugs- This test revealed a lot of problems with Scribble. Like I said, they are mostly annoying but manageable. But can you really call a project complete if you don’t make an honest attempt at fixing them?
- Write the final software- I didn’t build a machine to let me move a pen in an overly complex way- I built a machine to move a pen in an overly complex way by itself. Scribble’s software is highly technical, and I will have to break it into more than one article.
- Finalize the pen change mechanism- The pen change mechanism is tantalizingly close to being a done deal. Tricky engineering work is going on in the background. I’d hate to have to give up on it now.
In addition, I am making Scribble my first Big Project. That means it gets it’s own page with a listing of all associated articles, along with some commentary on the project as a whole. Said articles will also link back to the Big Project page. Hopefully this will make it easier to read the project articles. I should have the Big Project page up in a week or two.
No project ever goes all that smoothly. Scribble has had plenty of issues, some of which made me doubt whether I could actually finish. As usual with big projects you need the intelligence to identify problems, the flexibility to implement solutions, and the gumption to keep going even when it gets exhausting.
Getting Scribble to accept instructions from a computer is the next big milestone. Whether the next Scribble article will be hardware or software focused, I don’t yet know. The next article will likely be a few months from now- summer is rapidly approaching and there’s things I need to do while the weather cooperates.
Have a question? Comment? Insight? Post below!