Soldering a Micro USB Socket to a PCB

I’ve been working (for way too long now) on a development platform for future projects using a Teensy 4.0. A few weeks ago I was finally to the stage of creating the PCB.

Initially I planned to power the project with a 5V barrel plug as I’ve done in the past. Then I thought, why not also include a Micro USB socket since I always have those power supplies laying around. On this DEV board, I made both present so I could choose between them.

This was one of those last minute decisions which was not well thought out. I found the component I wanted on mouser which had a foot print available for Kicad. I designed the PCB without actually seeing the component. I had worked on this for so long I wanted to get the PCB ordered without waiting to see get the actual component in hand.

Its not like I’ve never seen a Micro USB socket before, but when I finally got them in the mail and looked at the size of the pins, my thought was “OH WOW how am I going to solder that???”

An alternative could have been a Micro USB breakout board such as Adafruit’s product #1833:

And, in fact, I may very well go back and add that footprint to overlay the existing footprint I used so I can use which ever I like.

But that doesn’t help me now. I’ve got 3 rather expensive PCBs of this design from OSH Park to use for now.

I went looking for help on soldering a Micro USB socket to a PCB and there is really not much help. The most apropos help came from StackExchange. Combining the advice I came up with a solution I thought most likely to work for me.

First, I was going to need some solder paste which I purchased from Amazon:

I also needed fine tweezers, flux paste, and isopropyl alcohol which I already had.

Flux and Solder Paste

The first step is to apply flux paste liberally to the footprint using a cotton swab. Then came the first tricky part: applying the solder paste. I have only soldered SMD components two other times in my life so I don’t have a good idea of how much to use.

First, I experimented applying a bit of solder paste to a piece of paper until I was sure I could control the flow. Once you squeeze to get the flow going, you then need to retract the plunger to stop the flow so you don’t get too much on the pads.

I figure given how tiny the pins are there is no reasonable way I’m going to be able to control the paste flow well enough to solder the pins. Instead, I simply put small dabs of solder paste on the component mounting pads like this:

 

 

If you look at the above picture closely you will see some solder smeared below the footprint. I got too much on the pad, used an exacto knife to remove it from the pad. A little was left behind. It didn’t seem to cause any issues.

Placing the Component

I took the whole assembly out to the garage to apply heat. I taped a cardboard box to the work bench and the PCB to the cardboard box (in retrospect, perhaps a cardboard box wasn’t the best solution).

Then using my shop magnifying light, I placed the MicroUSB as close to where I thought it needed to go. But that magnifying glass just didn’t have enough resolution to verify the pins were aligned to the pad.

I ended up using a flashlight and the inset magnifier on this magnifying glass to be able to verify I had the component in place.

With the USB socket in place, it looked like this:

Heating the Solder Paste

With everything in place, I fired up my trusty old heat gun on low and faced it straight down onto the board. I didn’t want to use high and risk nudging the component off the footprint.

If it took 30 seconds for the solder paste to melt, that was it. You could see it suddenly go from from dull grey to bright silver. Once I saw the transition, I held the heat gun there for another 10 seconds to be sure the solder on the pads below the component melted as well.

Once the PCB and component cooled, I used alcohol and a cotton swab to clean as much flux off the PCB as I could. Here is the result so far:

 

I tugged at the component to make sure it was reasonably well fastened to the PCB.

Soldering the Pins

Now for the really tricky part. As previously mentioned, I didn’t figure I would be able to apply solder paste thinly enough to solder the pins to the PCB. Instead I will use what is know as the swipe method. I will just run a solder iron with some solder on it across the pins.

First step was to install the finest solder tip I had onto the solder iron:

Then I used a cotton swab to apply flux paste liberally to the pins. One comment I read somewhere is to use leaded solder for this swipe technique. So I broke out my ancient spool of radio shack solder.

I cleaned the hot solder tip well (I’m using 750F), then applied just enough solder to see a bit of a bulge on the tip. I then ran the tip fairly quickly across the leads. Without checking my work yet, I then heated some copper braid against the pins to suck up the extra solder.

Now I carefully examined the pins with a flash light and magnifying glass. I could see all of the pins were bright sliver except the ground pin. I repeated the process again to make sure the ground pin, too, was soldered.

The second attempt appeared to be successful. I could see bright solder on all pins. So I cleaned the component and board up with alcohol.

Testing

I was ready to test, and now I found mistake #2 caused by my haste. I needed to have the edge of that foot print right up against the edge of the board. It was back kind of far as you can see in the above picture. How did I miss that?

Looking back at the PCB design, I see my mistake now.

I was lining the component up on the courtyard (the purple line) and not the actual component outline (the yellow line). Even then, I didn’t put the courtyard at the edge. Now I know to be careful, and fortunately the mistake is not so bad I need to file down the edge of the board to get it to work.

I’m only using this USB socket for power, not data, and the power supply will be a transformer, so I’m not overly worried about whether I got the data pins soldered properly. I just want to make sure there are no shorts between the power pins.

I used an continuity tester to make sure + and – pins weren’t some how shorted. I also tested the data pins the same way just to make sure they didn’t short to + or -. They were fine.

I then connected a power supply to the Micro USB socket and tested that I was receiving +5V on the +/- pads of the barrel jack. Success!

If I were using data pins, I absolutely would have tested this better. I would have cut up a micro USB cable and tested each data line to verify no shorts. But for this little project I’m not going to worry about it unless I find a problem down the road.

Follow Up

I cleaned the tip of the solder paste syringe using WD-40 Contact cleaner. I swear I had PCB cleaner but I must have dumped it when I got rid of all of the chemicals I once used for hand etching PCBs.

In the past, solder paste was a one-off need so I didn’t worry about storing it. I expect to build at least a couple more of these boards in the next few months so I shall store the solder paste in a ziplock bag in the fridge.

Yay! Now I can start soldering the rest of my Teensy 4.0 DEV board to see if I made any mistakes designing the PCB.

Posted in c-electronics | Tagged , | 10 Comments

IWISS SN-025 vs IWISS SN-28B Dupont Pin Crimper

Recently youtuber Michael Covington suggested using the model SN-025 Crimper rather than the SN-28B because it will wrap the tabs around the insulation rather than bury them into the insulation.

The top of the die for the SN-25 is round whereas the top of the SN-28B die is like a rounded ‘M’:

While I’ve gotten pretty good at crimping DuPont connectors over the years, I’m always looking for a better way.

Using the SN-25 crimper is about like using the SN-28B. My old video shows the process in excruciating detail:

While learning to use this new crimper I wrote down some additional notes that may be useful:

Strip 4 mm of insulation from the wire. I use a Jonard ST-550 to strip which make getting a consistent length pretty easy.

Once I got the correct size, I marked my stripper since this is its predominant use:

The insulation should be past the triangular wings, and the wire under the straight wings:

I’m going to crimp a female connector, so I insert a male connector just far enough to stay in the barrel end:

Insert the connector into the crimper die so that it is flush with the face of the die and place a little pressure on the tool to hold the connector in place.

This is where I have issues with this new tool. I’ve crimped around 10 connectors with it now and it is harder than the SN-28B to maintain the proper pressure on the connector to hold it in place without starting to deform it before I can get the wire in.

Insert the wire. You can’t see where the wire goes, but you should feel some friction as the insulation butts against the square tabs. Then crimp down

You can see here (if barely), the tabs are wrapped around the insulation:

I expect to build a cable harness for an upcoming project that will require quite a few DuPont pins. I’ll use the new tool and report findings if I decide I like the old tool better.

 

Posted in c-electronics | Tagged , , | 1 Comment

Testing 433MHz RF Modules

I picked up a box of RF modules like this on Amazon at the beginning of the year:

8 bucks for a box of 5 pairs!

In 2015 I had tested NRF24L01 transceivers and had trouble getting them working. I have avoided RF projects since. I’m thinking about remote control for an upcoming project so I wanted to find something cheap, reliable, and easy to use.

I found a really well written article on these transmitter/receivers on the site Last Minute Engineers.

That website will tell you everything you could possibly want to know about these modules! I will only add comments on a few changes I made for my testing.

I wanted a portable solution so I could walk around with either the transmitter or receiver to see the range performance. I had some spare buck/boost power modules so I paired those with 9V batteries and adjusted the output to 5V to power a pair of Arduino Nanos.

Here are the resulting units:

My code differed from the example somewhat. Rather than just transmit and print “Hello World” I needed something sequenced so I could detect lost packets.

The transmitter flashes the LED when it transmits and the receiver flashes the LED on for 100ms when it receives the next packet in sequence. If a packet is received out of sequence, the LED is flashed on for 250ms. This allows me to easily walk around with the receiver to determine how well it is functioning.

Here is the code for the transmitter:

#include 
#include  // Not actually used but needed to compile

int led = 13;

RH_ASK driver;

void setup()
{
    Serial.begin(9600);    // Debugging only
    if (!driver.init())
         Serial.println("init failed");
    pinMode(led, OUTPUT);
    digitalWrite(led,LOW);
}

void loop(
  ) {

int       i;
char      s[80];

for (i = 0; i <= 9999; i = i + 1) {
  sprintf(s, "%04d", i);
  Serial.print("Xmitting: ");
  Serial.println(s);
  Serial.print("strlen(s): ");
  Serial.println(strlen(s));

  digitalWrite(led, HIGH);
  driver.send((uint8_t*)s, strlen(s));
  driver.waitPacketSent();
  digitalWrite(led, LOW);

  delay(1000);
  }
} // loop

and here is the code for the receiver:

#include 
#include  // Not actualy used but needed to compile

int led = 13;

RH_ASK driver;

void setup()
{
    Serial.begin(9600);  // Debugging only
    Serial.println("Starting...");
    if (!driver.init())
         Serial.println("init failed");

    pinMode(led, OUTPUT);
    digitalWrite(led,LOW);
}

void loop(
  ) {

uint8_t             buf[12];
uint8_t             buflen = sizeof(buf);
int                 i;
int                 lasti = -1;

while (true) {
  if (driver.recv(buf, &buflen)) { // Non-blocking
      digitalWrite(led, HIGH);
      buf[buflen] = 0;
      Serial.print("Message: ");
      Serial.println((char*)buf);         
      i=atoi(buf);
      if (i != lasti + 1) {
        Serial.println("Missed msg");
        delay(250);
        }
      else {
        delay(100);
        }
      digitalWrite(led, LOW);
      lasti = i;
      }
  } // while
} // loop

My tests were outside in the open – nothing was between the transmitter and receiver.

Without installing any antenna, the range was about 30′. With the antenna installed as a straight wire, the range was 60′. I then coiled the antenna (as seen in the picture). The range of the coiled antenna was 57′. Almost as good as the straight antenna.

Unscientifically, I walked around the house with the receiver, leaving the transmitter on one side of the 2nd floor. It functioned thru walls fairly well. I couldn’t go everywhere in the house, but I could stay on the same side of the house, either floor, and it didn’t drop many packets.

A future project where I’m thinking of using this requires transmitting from inside my house to my truck next to the house. That worked fine even through a brick wall.

 

Posted in c-arduino | Tagged | Leave a comment

Unclogging Canon iP8700 Print Nozzle When All Else Fails

Let me state up front – I HATE inkjet printers. The ink is expensive and the print heads clog way too often for me. I would throw this iP8700 in the trash, but I occasionally want to print 11×17, particularly schematics. And once in a while proof photos, but I still always have a local lab do the final.

Because the printer can sit there for weeks or months, the heads clog and I almost always have to start the printing session with a head cleaning which wastes a good chunk of ink.

I got around the cost of ink by purchasing knock-off ink on ebay. I refused to do this for years because I was told by “the industry” that the colors of prints would be wrong. I was talking to a friend that prints huge canvas prints and asked him how he could afford the inks (he sells the prints for $100s of dollars so probably not as big of an issue for him). He told me he used knock-off inks and never had an issue. So I bought a set and printed my favorite test pattern and sure enough I could see no difference.

But even with cheap ink, eventually the nozzles have plugged so bad I had to replace the head. That was $100. Between ink and print heads it seems my cost to run this printer is in dollars / page, not pennies per page.

I needed the printer today for the first time in probably 6 months. I was able to print a black-only page w/o trouble but then it said I was out of black ink. So I put in a new cartridge did a nozzle test and magenta was extremely weak though the software said there was plenty of magenta ink.

Looking at the cartridge I could see it was iffy so I put in a new magenta. From that point forward I got no magenta at all:

I went thru at least 4 deep cleans and still not a hint of magenta.

I looked at my notes from the last time I went through this and the answer was to replace the heads. Nothing else had worked. I cannot justify replacing the heads again for using this printer maybe 10 times a year. I was ready to toss it.

After stewing for a while I decided to attempt clearing the nozzle with alcohol before tossing it.

What I’m about to show you will, I’m sure, invalidate any warranty you may have and could possibly screw your printer up worse. For me, if this didn’t work I was going to toss the printer anyway, so it was worth a shot.

  • Open the cover of the printer so you can access the ink cartridges.
  • Remove the cartridge with the faulty nozzle. You may need to remove the adjacent ones as well to see what you are doing.
  • I dipped the tip of a letter opener into (99.9%) isopropyl alcohol. This produces a very fine drop of alcohol to drop into the printer.

  • Using a flash light so I could clearly see, I placed 2 small drops on the magenta inlet for the print head.
  • I waited 60 seconds then put the ink cartridge back in place.
  • I ran a normal head cleaning operation and then a test pattern.
  • Lo and behold magenta ink even if not perfect:

One more thorough cleaning of the heads and I have it:

Note: the mottled effect in the pictures above are being caused by the scanner. The actual output is nearly perfect!

 

Posted in c-Misc | Tagged | Leave a comment

Making a [near] Perfect No-Flip Omelette

I like omelettes, but I hate under cooked eggs. For many years, the only way I would make my own omelette involved flipping it, but even with years of practice I had at best a 75% successful flip record.

A while back someone mentioned the ‘trick’ to getting a fully cooked egg without flipping – put a lid on the skillet. Of course! How simple. From there, I put trial and error to work until I created what I consider my perfect omelette.

At the bottom is a PDF of my recipe card. Here are some additional notes:

I always make a 2 egg omelette though this will work for 3 eggs as well. For years I put in a little 2% milk but then someone turned me on to using dry white wine instead. That seems to work well and keep the eggs looking more yellow.

I like to make an omelette on Sunday and use up any bits of meat and veggies I have left over. This week I had a left over petite sirloin steak from experiments trying to make a not-so-chewy sirloin steak so I used that in the following pictures.

Warm the skillet for about a minute before you add the butter. Use a temp lower than you would for an uncovered omelette because this recipe takes longer to get the top of the egg cooked. Once the butter is melted, make sure you fully coat the bottom of the skillet so the egg doesn’t stick and tear when you slide it out.

Make sure you whisk the eggs really good to get plenty of air bubbles into them. Normally I only put salt and pepper into the raw eggs UNLESS I want to use chili powder & cumin. Those I will mix into the eggs though the eggs come out looking brownish in the end.

Speaking of spices, try lots of different spices when doing this. My fav is Italian seasoning and I usually add a bit of garlic powder to that. Spiceology’s Cowboy Crust (espresso+chili+cumin) is another fav.

Here, the skillet is coated with butter and ready for eggs:

Now pour in the whisked eggs:

Let the eggs cooked undisturbed for 2 minutes. Don’t try to slide wet egg under the edges like you would do with a flipped omelette – not necessary.

After 2 minutes your eggs should look  about like this:

Note the position of the handle. I’ll be sliding the omelette off on the opposite side of the handle, so place the meat, veggies, and cheese to the left of the center so the egg can fold over them. Place any spices on the opposite side. Your omelette should now look about like this:

Put the cover on and cook about 3 minutes. You’ll want to play with this time to find what you consider perfectly cooked. I like just a bit of brown on the outside of the omelette.

After cooking and ready to slide out of the skillet:

To slide out, slide the egg around in the skillet to make sure you have broken any sticky spots. Then slide onto a plate and as the last 1/2 of the omelette comes out, flip it across the meat:

Add your favorite topping. Fletcher’s Hot Sauce is da bomb if you can find it.

Here is a 4×6 recipe card:

Omelette, No Flip

 

 

Posted in c-Misc | Tagged | 2 Comments

Starting a Lawn Mower with a Weak Right Arm

My right rotator cuff is partially torn. For the first 6 months of the injury, starting my 17 year old craftsman lawn mower was painful and pushing it not much better since it was not self-propelled. After another 6 months the pain was largely gone, but my arm is much weaker and I have to baby it to keep from inflaming the rotator cuff.

Once my arm stopped hurting, the craftsman mower wasn’t too bad to start because I could manually prime the cylinder with the priming bulb and start it almost always on the first pull. But having to manually push it and restart it every time I had to stop and pick something up was clearly not a great idea.

So I decided to purchase an expen$ive honda lawn mower that is self-propelled and has a blade clutch. Once it is running I never have to restart it. Once it is running…

The decision to forgo the electric start, at least for this mower, was a big mistake. This mower is very difficult for me to start. In cold conditions I have to pull it 7 or more times, by which time my shoulder is quite sore and I haven’t even started cutting grass.

I took the mower back and complained about the starting issue which they could not replicate. They blamed it on the gasoline which is ridiculous, IMO, because the gas was brand new non-Ethanol. Since then I’ve went thru several cans of fresh gasoline with no change in symptom.

Over time I realized their diagnoses issue was they would store the mower indoors and do a test start the next morning fully cold, but their shop is much warmer than my detached garage and I’m sure the 30-something mechanic has a much stronger arm.

As the summer progressed, the engine did get easier to start and as fall approached it got harder to start again.

Honda is supposed to be the Cadillac of lawn mowers. Well, OK, maybe Cadillac is no longer a gold standard. I have a Honda auto, generator, and pressure washer, and they all work very well. My other Honda small motors all have manual chokes.

This Honda lawn mower has an automatic choke that is controlled by a thermowax choke actuator:

As the engine heats up the pin extends which will cause the choke to open.

Many people have griped about the automatic choke working poorly due to the thermowax. I have a relative who does small engine repair, and he told me first thing I should do is replace that part. On ebay, it was quite inexpensive, so part purchased!

I took off the carb and pulled the old thermowax. Comparing the old to the new, the pin on the old thermowax was not retracted as far, so it seemed like that was the likely culprit. Sadly that really didn’t help much, if at all. I replaced the spark as well, but also no real difference. This is a new mower, so I wasn’t expecting it to help, but I wanted to rule it out. That really just leaves the carburetor.

(as of Apr 2024, I finally solved the problem which was due to the thermowax actuator not seating properly. See here).

This spring my plan was to replace the carb. But as I stewed on this expen$ive pile of metal, it occurred to me the main problem is my weak pull. A new carb probably isn’t going to matter outside of the choke and that has already been addressed.

So I pondered how I could increase my pull strength, short of surgery (which they say is not yet an option anyway).

There is a guy who built a device to automatically pull starter cords. Very cool device, but nearly 1/3 the cost of the mower. This would be a last resort for me:

https://pullstarters.com/

I started thinking about  the physical aspect of starting the mower. When I start a mower, I hold the push handle with my left hand, then pull the cord with my right using a quick snapping motion retracting my bicep and shoulder. What if I twist my torso at the same time?

I started doing that motion, and while the mower still needs 3 pulls to get started in fairly warm weather (75 degrees), I am not pulling as hard on my shoulder and it isn’t hurting nearly as much.

My process is:

  • Throttle to Max
  • Lightly pull starter cord until I feel the cylinder start to compress air
  • Bring the starter cord back into the housing to the point my arm is fully extended and my torso is twisted toward the mower.
  • Simultaneously pull cord with my bicep and twist torso in the other direction trying not to pull shoulder back

In researching to find if anyone else suggests twisting the torso to start a mower (I find nothing), I did find an exercise called the lawnmower pull. Hmmm, maybe I’ve been starting mowers wrong my entire life?

This demonstration shows quite well the motion I use:

I really wish Honda would not have put on an automatic choke or at least include a priming bulb like my craftsman had. It was 17 years old and still started on the first pull every time!

By the way, DO NOT let the motor shut off until it is fully warmed. This is a big disadvantage to the thermowax system – it will heat up enough to disable the choke, but the engine still isn’t warm enough to restart without a choke and you will find you can’t start the mower until you have to let it cool down far enough to re-engage the choke.

Posted in c-Misc | Tagged | 3 Comments

Prodigy P2 Brake Controller Reports 11, 12, 14, and 17 When Adjusting Power to Brakes

I have had a Prodigy P2 brake controller for at least 10 years now and it performs well for me.

Yesterday I picked up my travel trailer, which has been sitting unused for the last year. After I get  the trailer hitched up and everything connected, my final test is to manually apply trailer brakes as I’m rolling to verify they work.

When I applied brakes manually, instead of getting the normal voltage reading I expected of 5.0, I was getting various indications way too high: I at least saw 11, 12, 14, and 17 on the display. That made no sense. I tried readjusting the brakes and most of the time all I could get were those codes and the brakes clearly weren’t working.

Looking at the manual, which I keep in my glove box:

Click to access N90885.pdf

There is no explanation what these codes might mean. The brakes were connected – I was getting the .c. code when the brakes were off.

I had my phone with me so I tried looking the codes up and still no explanation.

While fiddling around I noticed the trailer lights had stopped working. I ended up scraping corrosion off of the connector to get the trailer lights working. When I did that, lo and behold, the brakes started working too.

So, just because the controller reports .c. and doesn’t report any errors, doesn’t mean it is actually connected properly. There might be just enough corrosion to cause undetectable problems.

Posted in c-Misc | Tagged | Leave a comment

PDP-11/RT11: Card Readers and Batch Jobs

I thought I was done with the PDP-11 project, but while reading the end of Assembly Language for the PDP-11 (Knapp), appendix C discussed how to set up the PDP-11 to allow students to compile and run their assignments using batch jobs.

This was exactly how we used the PDP-11 in college – it only had one DECWriter connected to it – no way a bunch of students could share a single terminal. For that matter, the DEC-10 mainframe the university also had usually accessed with batch jobs – my first year there were a total of 4 CRTs available for student use. So I decided to see if I could emulate my really old days: input from card reader, output to printer.

I had tried to do this when I was initially learning RT11, but it wasn’t making sense to me. The “Notes For the Instructor” are in section C.2 of Assembly Language for the PDP-11. The full explanation of the BATCH program can be found in Appendix A of RT-11 System User’s Guide.

Accessing the Line Printer

This is pretty simple, in SimH, just attach the printer to a disk file (-n specifies a new file be created, overwriting an old one if it exists):

sim> att -n lpt lpt.out
sim> show lpt
LPT address=17777514-17777517, vector=200, BR4
attached to ./lpt.out
sim> cont

To use the line printer in RT11, you must first load it’s driver:

.LOAD LP

Now, anything sent to LP: will go to the physical file specified in the attach command:

.COPY TEST.DAT LP:
Files copied:
DK:TEST.DAT to LP:TEST.DAT

To look at the output, you have to close the file first. In Windows, you can see the file with TYPE or CAT in Linux.

control-E
Simulation stopped, PC: 151300 (ASR R5)
sim> det lpt
sim> type lpt.out
♀TEST

sim> att -n lpt lpt.out
%SIM-INFO: LPT: creating new file: lpt.out
sim> cont

The weird character shown in the output (♀) is the form feed character which will cause the printer to advance to a new page.

Accessing the Card Reader

You don’t have to run batch jobs from the card reader. You can use a mag tape, or even a disk file. But I want to maintain as much authenticity as I can, so I needed to figure out how to use the card reader.

When you start SimH, the card reader device (CR) is not enabled. You need to do this before starting RT-11, I put these SimH commands into my boot.ini:

sim> set cr enable
sim> set cr translation=029

Once you’ve booted RT11, you need to load the card reader driver:

.LOAD CR:

When you are ready to use the card reader, you must first attach an ASCII to it, and then RESET it:

control-E
sim> det cr
sim> att -a cr .\example-batch.cdr
%SIM-INFO: CR: unit is read only
sim> set cr reset
sim> show cr
CR no EOF pending, address=17777160-17777167, vector=230, BR6
285 cards per minute, translation=029
attached to ./example-batch.cdr, read only, CR11, auto EOF
read check, ASCII format
sim> cont

The card reader is now ready, so copy its cards to a disk file:

.COPY CR: TEST.DAT
Files copied:
CR: to DK:TEST.DAT

.TYPE TEST.DAT
$JOB /BANNER
$MESSAGE TEST BATCH
$CREATE/LIST EXAMPL.MAC
.TITLE EXAMPL FOR BATCH
.MCALL .PRINT,.EXIT
START: .PRINT #MESSAG
.EXIT
MESSAG: .ASCIZ /HELLO WORLD!/
.END START
$EOD
$MACRO EXAMPL EXAMPL/OBJECT EXAMPL/LIST
$LINK EXAMPL EXAMPL/EXECUTE
$PRINT/DELETE EXAMPL.LST
$RUN EXAMPL
$DELETE EXAMPL.OBJ+EXAMPL.SAV+EXAMPL.MAC
$DIRECTORY DK:EXAMPL.*
$EOJ

If you were able to copy from CR: then you are ready to execute batch jobs from it.

Running Batch Jobs

Batch jobs are processed by an RT11 program called BATCH. For specifics on the BATCH language, see Appendix A of RT-11 System User’s Guide. I’m going to illustrate the most common here.

Prepare the Card Deck

To run a batch job requires a card file of all of the commands and data you are going to need. I have prepared an example file on my PC  called  example-batch.cdr. The contents of that file were displayed above.

Here is a quick summary of the commands I use:

  • $JOB – Indicates the beginning of the batch job.
  • $CREATE – creates a file called EXAMPL.MAC. The next cards, up to the $EOD will be copied into the file. The /LIST option indicates to display the cards as they are being read.
  • $EOD – indicates a data stream is done, the next card will be a batch command.
  • $MACRO – Compiles EXAMPL.MAC into EXAMPL.OBJ and generates a listing.
  • $LINK – Links EXAMPL.OBJ into EXAMPL.SAV.
  • $PRINT – Prints the EXAMPL.LST file to the printer.
  • $RUN – executes the EXAMPL program
  • $DELETE – deletes the files created by this job.
  • $EOJ – indicates this is the end of the job

Reset Card Reader and Printer

Make sure the printer and card reader are ready to go:

control-E
Simulation stopped, PC: 152644 (BR 152622)
sim> det lpt
sim> att -n lpt lpt.out
%SIM-INFO: LPT: creating new file: lpt.out
sim> det cr
sim> att cr .\example-batch.cdr
%SIM-INFO: CR: unit is read only
sim> set cr reset
sim> cont

Run BATCH

Now we setup and run the BATCH program and tell it to accept its input from the card reader:

.LOAD BA:,LP:,CR:
.ASSIGN LP: LOG
.ASSIGN LP: LST
.R BATCH
*CR:
TEST BATCH

END BATCH
.

Had this been a real card reader / line printer, BATCH would just continuously read cards from the card reader and output results to the printer.

Looking at the Output

sim> det lpt
sim> type lpt.out
♀

$JOB /BANNER

$MESSAGE TEST BATCH

$CREATE/LIST            EXAMPL.MAC

.TITLE  EXAMPL FOR BATCH
        .MCALL  .PRINT,.EXIT
START:  .PRINT  #MESSAG
        .EXIT
MESSAG: .ASCIZ  /HELLO WORLD!/
        .END    START


$EOD

$MACRO  EXAMPL  EXAMPL/OBJECT   EXAMPL/LIST

ERRORS DETECTED:  0
♀EXAMPL FOR BATCH        MACRO V04.00  2-FEB-95 15:34:49 PAGE 1


      1                                 .TITLE  EXAMPL FOR BATCH
      2                                         .MCALL  .PRINT,.EXIT
      3 000000                          START:  .PRINT  #MESSAG
      4 000006                                  .EXIT
      5 000010     110     105     114  MESSAG: .ASCIZ  /HELLO WORLD!/
        000013     114     117     040
        000016     127     117     122
        000021     114     104     041
        000024     000
      6         000000'                         .END    START
♀EXAMPL FOR BATCH        MACRO V04.00  2-FEB-95 15:34:49 PAGE 1-1
SYMBOL TABLE

MESSAG  000010R         START   000000R

. ABS.  000000     000
        000025     001
ERRORS DETECTED:  0

VIRTUAL MEMORY USED:  8192 WORDS  ( 32 PAGES)
DYNAMIC MEMORY AVAILABLE FOR  60 PAGES
EXAMPL,EXAMPL=EXAMPL



$LINK   EXAMPL  EXAMPL/EXECUTE


$PRINT/DELETE EXAMPL.LST


$RUN    EXAMPL

HELLO WORLD!

$DELETE EXAMPL.OBJ+EXAMPL.SAV+EXAMPL.MAC


$DIRECTORY DK:EXAMPL.*

 02-FEB-95
EXAMPL.BAT     1  02-FEB-95
 1 FILES, 1 BLOCKS
 4691 FREE BLOCKS

$EOJ
sim>

This is a clunky process for a single job, but if you’ve got many people wanting to use the computer requiring many batch jobs be processed, it becomes much more efficient.

Automated Printing

While working with RT11 I wanted my output to go straight to a printer. Not much luck with that.

I had a dot matrix printer connected to my Raspberry Pi/PiDP-11 hardware. While I could print from bash, I never was able to get SimH to connect directly to the printer. I guess the designers never really expected someone to do that.

Windows is even worse. Eons ago, I guess, MicroSoft decided no one would need to print from the DOS box. The ability to copy to LPT in DOS is pretty much dead and gone.

What I did find works is to run notepad and tell it to print the LP’s output file. I ended up creating a nice little SimH command file such that when I want to force LPT.OUT to print, I just do this:

control-E
do print.cmd

print.cmd detaches LPT, prints the file using notepad, and then reattaches:

detach lpt
!start /min notepad -p lpt.out
sleep 5s
del lpt.out
attach lpt lpt.out
cont

To be honest, I don’t use notepad, but a text editor called Textpad – it has been my text editor of choice since the 90’s. Using it, I can tell it if I use the -p option on a file with an *.out extension, it will print it in landscape, using a specified font, so I get a pretty nice listing:

I believe that is enough “RETRO Computing” for a while! I’ve got new hardware for another Microcontroller project just waiting…

Posted in c-retro | Tagged , , | Leave a comment

Using the PDP-11 RT11 Operating System

This is a quick video on how to use RT11 running on the PiDP-11 hardware with simh providing the PDP-11 emulation.

Covers a little about listing, copying, and deleting files. Shows how to compile, link, and run a MACRO-11 program. Shows how to invoke and exit the KED editor.

In this video you will see me type BACKSPACE and you will see “\<letter>” when I do.

YouTube user Lawrence D’Oliveiro pointed out that if you use SET TT SCOPE, the backspace will function properly for a CRT monitor. It will do a destructive backspace rather than print “\” followed by the character deleted.

Posted in c-retro | Tagged , , | Leave a comment

Using the PDP-11 (PiDP-11) Front Panel to Enter Data and See Results

Last blog post, I entered a very simple program into the PDP-11 using the front panel switches and then ran it. All of the input was hard coded, and the output had to be examined by dumping memory. Here is that post:

Entering and Running a Tiny Program from the PDP-11 (PiDP-11) Front Panel

For this post, I am going to write a small program that accepts two numbers from the switch register, multiply them, and display the result on the front panel. One can then continue to input and multiply numbers or terminate the program and let it return to the monitor.

I am NOT going to enter this program though the switch panel. I will initially load it from the monitor, then use the front panel to interact with the program.

Here is the program:

.TYPE CONMUL.MAC
        .title  Console Multiply
                ; Enter 2 numbers through the front panel, multiply them
                ; and display results on the front panel.
        .list   meb             ; lists macro expansions producing binary code
        .mcall  .exit           ; define .exit macro
        .enabl  ama
start:
        mov     #10000,R0
        halt                    ; Should display %10000 and halt
        mov     177570,a        ; Place user's first # in <a>

        mov     #20000,R0
        halt                    ; should display %20000 and halt
        mov     177570,b        ; Place 2nd # in <b>

        ; c = a x b
        mov     a,R1            ; R1 <- a
        mul     b,R1            ; R1 <- b x R1
        mov     R1,c            ; c  <- R1

        mov     c,R0
        halt

        tst     177570          ; if 0 in SW register, quit
        bne     start

        .exit                   ; return to the monitor
a:      .blkw   1               ; 1 word block containing <a>
b:      .blkw   1
c:      .blkw   1
        .end    start           ; program will begin executing at 

Code Notes

When I move #10000 and #20000 to register R0 and then HALT the CPU, R0 displays on the DATA display register of the front panel. This is how I prompt the user: if there is a %1 in bits 14-12, then the CPU is awaiting the first number. If there is a %2, then it is awaiting the 2nd number.

The switch register is read by moving its contents. So this instruction will move the contents of the switch register to the variable <a>:

 mov 177570,b ; Place 2nd # in <b>

To display the result of the multiply operation, which is in <c>, I move c to register R0.

Finally, I test the switch register for 0 (TST) and if it doesn’t contain 0 (BNE), I jump back to the beginning of the program.

Here is the compile listing so you can see all the memory addresses. The listing shows the program’s starting location as %00000. It will actually load at %1000, so if you want to directly examine memory, don’t forget to add %1000 to the addresses shown in this listing:

.TYPE CONMUL.LST
CONSOLE MULTIPLY        MACRO V04.00  28-JAN-95 00:00:19 PAGE 1


      1                                         .TITLE  CONSOLE MULTIPLY
      2                                                 ; ENTER 2 NUMBERS THROUGH THE FRONT PANEL, MULTIPLY THEM
      3                                                 ; AND DISPLAY RESULTS ON THE FRONT PANEL.
      4                                         .LIST   MEB             ; LISTS MACRO EXPANSIONS PRODUCING BINARY CODE
      5                                         .MCALL  .EXIT           ; DEFINE .EXIT MACRO
      6                                         .ENABL  AMA
      7 000000                          START:
      8 000000  012700  010000                  MOV     #10000,R0
      9 000004  000000                          HALT                    ; SHOULD DISPLAY %10000 AND HALT
     10 000006  013737  177570  000062'         MOV     177570,A        ; PLACE USER'S FIRST # IN %lt;a%gt;
     11
     12 000014  012700  020000                  MOV     #20000,R0
     13 000020  000000                          HALT                    ; SHOULD DISPLAY %20000 AND HALT
     14 000022  013737  177570  000064'         MOV     177570,B        ; PLACE 2ND # IN %lt;b%gt;
     15
     16                                         ; C = A X B
     17 000030  013701  000062'                 MOV     A,R1            ; R1 <- A
     18 000034  070137  000064'                 MUL     B,R1            ; R1 <- B X R1
     19 000040  010137  000066'                 MOV     R1,C            ; C  <- R1
     20
     21 000044  013700  000066'                 MOV     C,R0
     22 000050  000000                          HALT
     23
     24 000052  005737  177570                  TST     177570          ; IF 0 IN SW REGISTER, QUIT
     25 000056  001350                          BNE     START
     26
     27 000060                                  .EXIT                   ; RETURN TO THE MONITOR
        000060  104350                          EMT     ^O350
     28 000062                          A:      .BLKW   1               ; 1 WORD BLOCK CONTAINING %lt;a%gt;
     29 000064                          B:      .BLKW   1
     30 000066                          C:      .BLKW   1
     31         000000'                         .END    START           ; PROGRAM WILL BEGIN EXECUTING AT 
CONSOLE MULTIPLY        MACRO V04.00  28-JAN-95 00:00:19 PAGE 1-1
SYMBOL TABLE

A       000062R         B       000064R         C       000066R         START   000000R

. ABS.  000000     000
        000070     001
ERRORS DETECTED:  0

VIRTUAL MEMORY USED:  8192 WORDS  ( 32 PAGES)
DYNAMIC MEMORY AVAILABLE FOR  67 PAGES
DK:CONMUL,DK:CONMUL=DK:CONMUL

To compile, link, and load:

.COMPILE CONMUL
ERRORS DETECTED: 0

.LINK CONMUL

.RUN CONMUL

Program Operation

One the program starts, it will display %10000 in the display register (only bit 12 lit). This is the indication it is ready for the first number. In this picture, you can see it is prompting with %10000 AND I have already placed %2 into the switch register. It is just waiting for me to press CONT:

I press CONT and I am prompted for the second number with a %20000 (only bit 13 lit). In this picture, you can see the %20000 prompt AND I have already placed 3 into the switch register:

Once I press CONT, the multiplication is done and the results are shown in the DATA display register as %6:

To exit the program, I set the Switch Register to %0, and press continue. The program will exit, resume the monitor and the lights will return to the normal flashing pattern you would see when the monitor is running:

A video of the program in operation can be seen here:

 

Posted in c-retro | Tagged , , , | Leave a comment