Sunday, April 5, 2020

Setting Up MegaEnigma to decode the Rasch Message, a 1942 intercept by H.M.S Hurricane

This is part of the documentation of MegaEnigma, a Universal Enigma Machine Simulator:

In the following videos, the machine will be set up to decode a real U-Boar message, available here:

MegaEnigma 1/8: All Menus and Brightness adjustment


MegaEnigma 2/8: Selecting an Enigma Machine model.


MegaEnigma 3/8: Selecting the Rotors


MegaEnigma 4/8: Ring Settings


MegaEnigma 5/8: Viewing the installed plugs.


MegaEnigma 6/8: Confirming All The Settings


MegaEnigma 7/8: Setting up the starting rotor position.


MegaEnigma 8/8: Decoding the message (BOOT KLAR)


Additional Menus:

MegaEnigma: UKWD, Software Plugs and UHR Switch


MegaEnigma: UKWD menu appears for machines that feature it.


MegaEnigma: UKWD menu: Viewing plugs in UD and BP notation


MegaEnigma: UKWD menu: editing plugs


Tuesday, March 17, 2020

Enigma UHR Switch Test Vectors

While working on an Arduino based Uhr Switch to be externally attached to an Enigma Machine Simulator, the need to verify the correctness of the implementation arose.
https://www.instagram.com/p/B9wicTznNrp/
https://www.instagram.com/explore/tags/megaenigma/

The UHR switch is described here:
https://www.cryptomuseum.com/crypto/enigma/uhr/index.htm

A reference implementation can be found here:
http://people.physik.hu-berlin.de/~palloks/js/enigma/enigma-u_v25_en.html

Most likely nobody needs these, but here they are just in case:

Enigma UHR Switch Test Vectors...

Friday, March 13, 2020

Pure software debouncing of a noisy RE11 Rotary Encoder / Audio Digital Potentiometer without using external capacitors

Started working on en Enigma UHR switch. This needs a rotary encoder to simulate the original 40 position switch.

https://www.cryptomuseum.com/crypto/enigma/uhr/index.htm

Jumped on eBay, searched for "ec11 encoder" and quickly decided on a 20 step rotary encoder. A few days later it showed up in the mail.

From previous work on rotary encoders, I remembered they have a common pin, and two pins that produce a square wave that's out of phase. If the pins are read together they are supposed to return a sequence like 11->10->00->01. This is called Grey Code, where two successive states only differ by 1 bit.

One side of the switch has 3 pins the other side 2. The two pins on one side get shorted together when the shaft is pushed. The three pins on the other side are the rotary encoder pins. The data sheet says that the center one is the common and the other two produce the out of phase square waves.

Before wiring anything, I decided to test continuity with a meter. The two pins measure open at rest and continuity when the encoder shaft is pushed in. That was easy enough. The rotary encoder pins were a different story, nothing measured continuity, rotating it did not help, measuring resistance, the meter briefly jumped from open, but it never showed continuity. Thinking that this encoder must be bad, I measured another, but got the same result.

Ok, time to wire them up to an Arduino and see what the pins are doing. The datasheet says to connect the outside pins to VCC using a 10k resistor and connect the middle pin to ground.

Jumpers were soldered to the encoder leads. The center pin, in green was connected to ground. The left and right pins were connected directly to D12 and D11. The Atmel/Microchip ATmega 328p used in the Arduino Nano has internal pull-up resistors that are activated by setting a pin as input and then writing high to it.Reading the pin will then return 1 if not connected to anything, or 0 if connected to ground.


The first step is to see what the pins are doing as seen by the Arduino. The code below uses the following fast pin library
https://github.com/mikaelpatel/Arduino-GPIO

 #include "GPIO.h"  
 GPIO<BOARD::D11> PlugJ;  
 GPIO<BOARD::D12> PlugK;  
 GPIO<BOARD::D13> LAMP;  
 void allPlugsInput()   /*xls*/  
 {  
  PlugJ.input();  
  PlugK.input();  
  PlugJ.high();  
  PlugK.high();  
 }  
 void setup() {  
  // put your setup code here, to run once:  
  Serial.begin(9600);  
  LAMP.low();  
  LAMP.output();  
  allPlugsInput();  
 }  
 void showrawpins()  
 {  
  byte EncA = PlugJ.read();  
  byte EncB = PlugK.read();  
  Serial.print(EncA);  
  Serial.println(EncB);  
 }  
 void flashD13()  
 {  
  static int lamptimer = 0;  
  lamptimer++;  
  if (lamptimer > 256)  
  {  
   LAMP.low();  
  }  
  else  
  {  
   LAMP.high();  
  }  
 }  
 void loop() {  
  // put your main code here, to run repeatedly:  
  flashD13();  
  showrawpins();  
 }  

This is the output from this code


This encoder is always outputting 11, turn the shaft and some digits change, but it always returns to 11.

Scrolling up, we see that the pins change when turned.


Let's add some code to filter out the at-rest 11 state and see whats going on more clearly.

When the input pins are not showing 11, this function prints their values. When the pins return to 11, it prints "done" once and goes back to listening for a change.

 void showrawenc()  
 {  
  byte EncA = PlugJ.read();  
  byte EncB = PlugK.read();  
  static byte changing = 0;  
  if (EncA + EncB != 2)  
  {  
   Serial.print(EncA);  
   Serial.println(EncB);  
   changing = 1;  
  }  
  else  
  {  
   if (changing == 1)  
   {  
    Serial.println(F("done"));  
    changing = 0;  
   }  
  }  
 }  

Here is the output from calling this function in loop()

The encoder is being turned clockwise (CW)


And here we see the encoder being turned counter-clockwise (CCW)


Now, a pattern begins to emerge.

This encoder is always outputting 11, when turned clockwise, it starts emitting a lot of 10, followed by a single 00, before returning to 11

When turned counterclockwise, it starts with 01, then 00, then 11.

Turning the shaft rapidly shortens the initial repeat pulses, but most of the time it keeps the 00, followed by 11.


We need a function that looks for an initial 10 after 11, disregarding any other values until 11 is returned again. Report a single clockwise event. If an initial 01 is read after 11, disregard any other values until 11 is returned again. Report a single counter-clockwise event.

To keep this short, here is the final debounced routine.

It reads the encoder pins either one at a time using the read() function or both at the same time accessing PINB.

It sits in state 0, disregarding input 11 until that changes. If the first value is 10 it sets the direction to 1 and jumps to state 1. If the first value is 01, it sets the direction to -1 and jumps to state 1. In the meantime, the function is constantly returning 0. A direction cannot be reliably detected until a 00 value is read in state 1, the direction value is returned once and cleared out. When a 11 is read, the function jumps to state 0, and re-arms itself  to look for the initial direction value.

 //debounced rotary encoder logic  
 signed char rotaryencoder()  
 {  
  static byte state = 0;  
  static signed char dir = 0;  
  signed char v = 0;  
  //read pins one at a time  
  //byte EncA = PlugJ.read(); //EncA must be input() and high()  
  //byte EncB = PlugK.read(); //EncB must be input() and high(), connect C to ground  
  byte ENC = PINB;        //read both pins at a time  
  byte EncA = (ENC & 0x08) >> 3; // isolate bit (&) 0x08 = D11 and shift right to turn into 1 or 0  
  byte EncB = (ENC & 0x10) >> 4; // 0x10 = D12  
  switch (state)  
  {  
   case 0:  
    {  
     if (EncA + EncB != 2) // at rest encoder outputs 11  
     {  
      if (EncA == 1)    // followed by many 10 when turning right  
      {  
       dir = 1;  
       state = 1;     // detect the rising edge and then wait until it goes 00 then back to 11  
      }  
      if (EncB == 1)    // followed by many 01 when turning left  
      {  
       dir = -1;  
       state = 1;  
      }          // if output is 00, we missed 01 or 00, stay in this state  
     }  
     break;  
    }  
   case 1:  
    {  
     // once we react to the first 01 or 10, many more, followed by 00 will follow  
     if (EncA + EncB == 0) // after initial 10 or 01, we must have a 00 to confirm it was valid  
     {  
      v = dir;  
      dir = 0;  
     }  
     if (EncA + EncB == 2) // once we see 11 again, the encoder is idle, go back to detecting a change  
     {  
      state = 0;  
     }  
    }  
  }  
  return v;  
 }  

This function represents several improvements over its initial implementation. The first improvement was to add logic to stay in state 0 if 00 was the first value read after 11. This worked fine when turning the shaft slowly. Turning the shaft quickly resulted in the routine reporting the opposite direction sometimes.

These missed events were further filtered out with the second improvement, looking for a 00 value in state 1. A good turning event is as follows 11->01->00->11

The routine as shown above is very stable and correctly reports slow or fast turns in either direction without using any external filtering components such as resistors or capacitors or combinations thereof.

The main loop is as follows:

 void loop() {  
  // put your main code here, to run repeatedly:  
  flashD13();  
  //showrawpins();  
  //showrawenc();  
  static byte uhr = 0;  
  signed char v = rotaryencoder();  
  uhr += v;  
  if (v != 0)  
  {  
   Serial.println(uhr);  
  }  
 }  

Here is an example of the encoder being rotated very fast in a clockwise direction. There is a single mis-read event at the 10-11 mark, but it will be masked by successive events, the user should not notice as the end value (18) is significantly higher than the initial value of 1. Turning the knob slowly produces corrects results all the time. Reading noisy rotary encoders is tricky, but the polling code shown above does a fairly good job of counting valid events while disregarding noise that could result in the encoder being read as being turned in the opposite direction.


Some closing notes:

Before introducing complexity in your designs, in the form of external components or complicated code, first try to understand the component you are working with. Observe its raw output, then write code to handle most of the cases. Finally, refine the code by adding more cases until it works with an acceptable percentage of reliability.

Use your internal pull up resistors. Configuring a pin as input and writing high to it, enables internal pull up resistors. This simplifies the external circuitry.

The above code implements a state machine to turn the following inputs 11->01->noise->00->noise->11 into a single valid turning event in a simple polling routine without using an interrupt service routine (ISR). The code can be expanded to keep track of multiple rotary encoders by changing the way the state variable is stored, but that is left as an exercise to the reader ;)


Wednesday, January 29, 2020

Mega Enigma battery endurance test using AA batteries concluded

An endurance test was conducted to determine how long will MegaEnigma run on a set of AA batteries. A previous test determined that a set of AAA batteries kept the unit running in standby mode for 21.8 hours.


First an AA battery holder was laser cut and assembled.


The male pin to 9V battery plug adapter was made to allow an unmodified battery compartment to plug into an unmodified arduino power plug. Note the polarity of the adapter is reversed in order to correctly supply 6.4V center positive at the 9V male plug.


The self monitoring sketch was uploaded and allowed to run until the batteries could not power the unit. Then the reporting sketch was uploaded. Here is the point where the monitoring sketch stopped recording new values.


And the reporting logic correctly identifies the maximum value recorded in the buffer.


And this translates to 62.75 hours of continuous standby using fresh AA batteries on a unit with Blue 16-segment leds. A significant increase in runtime from the previously obtained 21,8 hours on a set of AAA batteries.


The next question is what will the standby time be when using White 16-segment leds.

Sunday, January 26, 2020

Mega Enigma Assembly Steps

1) Power Jack
2) Keys
3) Arduino Mega
4) 16 Segment Displays
5) Lamp Field
6) Plugboard sockets
7) Shorting PCB
8) TVS Diodes
9) Copper bus on common side of TVS Diodes
10) Header
11) Bend Header
12) Solder Plugboard Header to Main Board

Saturday, January 18, 2020

Mega Enigma Software V12 Released

This version focuses on operational realism of the enigma machine.

Sometimes, modules get a little hacky from adding features one at a time. Once all the features are defined, it is better to rewrite a function from the ground up and it comes out cleaner.

ProcessEnigma() in EnigmaGUI.ino has been rewritten, particularly case 2 in the finite state machine.

The machine has been designed to operate as follows:

Pressing a key first moves the rotors then lights up the correct result. While the rotors are moving, the contacts are not making, so nothing is illuminated.

A key must be held pressed down to illuminate a result, releasing the key turns off the lamp.

Two keys can be pressed at the same time. The way the keyboard circuit is arranged, the two top rows are in the same zone, while the bottom row is on a separate zone. The rotor up and down keys are in a separate zone. The menu key is in the same zone as the bottom row. Pushing two keys in the same zone corrupts what is displayed. Pushing keys in separate zones does not corrupt the display. Normally, only one key is pushed at a time in an enigma machine, so this zone arrangement is not part of the normal operating procedure.

If the menu key is pressed while a key is being held down and its result is illuminated in the lamp field, exiting the menu restores the current position of the rotors and the illuminated result.

While holding a key down, the rotors can be changed. The lever mechanism of the enigma machine allows each rotor to be advanced while a key is held down, but the ratchet mechanism does not allow an engaged rotor to be moved backwards while a key is pressed.

The fast rotor always turns, so if a key is pressed, it cannot be moved back to the initial position, only advanced. The middle rotors can be moved back until the stepping notch is engaged.

Changing a rotor with a key pressed down changes the output shown in the lampfield.

The plugboard is scanned dynamically. Changing a plug with a key pressed down changes the result shown in the lampfield.

The original Enigma Machine uses a two way switch in each key. If a key is not pressed, it is connected to its corresponding lamp in the lamp field. Pressing a key down connects the battery to the key and sends it to the entry rotor (ETW). The current goes through the rotor maze in and out of the reflector (UKW), and back through the rotor maze into the ETW and through an unpressed key it connects to the lamp field.

Lets use the default settings for an M4 machine with a B UKW and a Beta thin wheel and the rotors at AAAA. Pressing the V key results in E lighting up. V and E are in different zones, so both keys can be pushed down simultaneously without display corruption.

If, while holding V down, the E key is pressed, the path to the lamps would be disconnected in both ends in a real enigma machine, nothing lights up. In this simulator, this behaviour is modeled in software.

Releasing only the V key lights up the V lamp, releasing only the E key lights up the E lamp. Changing the rotors with both V and E pressed illuminates two different lamps in the lampfield. Installing or changing a plug from V or E to any other plug will illuminate two lamps in the lampfield.

So, generally, pressing a key and the key corresponding to its result simultaneously results in both lamps turning off as there is no path to the lamps.

The sequence to illuminate a key in an external USB lamp field is sent out the serial port when a key is pressed.

If the Mega Enigma Machine Simulator is connected to a computer, the Arduino IDE Serial Port Monitor can be opened used to interact with the simulator.

Sending !aaaa sets the rotors to position AAAA. Sending text encodes it. Changes to the machine configuration cannot be made through the serial port, only the rotor position can be changed.

Other unchanged features are:

Holding down the menu key results in an emergency zeroisation. All the settings are cleared and returned to a default M4 machine with B UKW and Beta additional wheel. The ring is reset to AAAA and the rotor position is changed to XXXX to indicate the settings have been cleared. Any physically installed plugs would need to be removed to complete the key erasing procedure. If software plugs were in use, they are cleared. The built in UKWD is reset to 0 as well.

The menu key is ignored for a fraction of a second when the simulator exits out of the menu and returns to the operational mode. This makes it easier to not reenter the menu and stay in operational mode if the menu key is pressed rapidly to advance through the menus and exit.

A hex uploader can be downloaded below:

https://gitlab.com/arduinoenigma/megaenigma/tree/master/compiled/MegaEnigmaV12

Full Source Code:

https://gitlab.com/arduinoenigma/megaenigma/tree/master

Monday, January 13, 2020

Measuring Battery Run Time By Writing Checkpoints to EEPROM

One way to measure how long a device runs on batteries is to use another Arduino with a Light Sensitive Resistor. Can we do better than that and have the device self monitor without using any external attachments?

How to measure how long will a device run on batteries by writing time stamps to EEPROM.

The key to this algorithm is to either use an external stimuli to set a ram variable or use a different sketch to write a special variable to EEPROM to enter a special routine that writes the value of millis() to EEPROM. Once this special routine is entered, the EEPROM flag that was used to enter is cleared. This way when the device under test runs out of batteries and starts rebooting, the recording routine is not entered again. In EEPROM we will have a series of ever increasing 32 bit values. The only thing remaining is to read all the values and find the maximum. In case the device reboots while writing to EEPROM, an additional check is that the maximum value must equal to the second greatest value plus whatever the time increment used. 

In order to implement a wear leveling algotithm, the time values are written to an EEPROM zone in a circular buffer fashion.



Check out the actual code used to implement this functionality:
https://gitlab.com/arduinoenigma/megaenigma/commit/c74146f7ade4ea219ac390ada9493e9dc439daf9#a878fb2d118cf18caae6e3fd3392674ce8988b42_39_42

The timing routine was run with a used battery and the recorded values were displayed. EEPROM address 701 contains the value of millis() when the recording function was first entered, subsequent values are recorded every minute.


This 9V battery was used, so after 58 minutes, the machine rebooted and stopped recording values. The remainder of the buffer contains 0 left over from the initialization procedure.


Trying again with a fresh set of batteries. After the batteries are allowed to run down, connecting to the device shows a message stating that the endurance test has been run.


This time the test ran for a longer time. The circular buffer was configured from addresses 701 to 3501, storing a 4 byte values lets us write 700 values before reaching the end of the buffer. If a value is stored every minute, the buffer will store 11 and a half hours of data. 


Memory location 3133 contains the highest value recorded, 78540001 milliseconds or 21.8 hours. The value in 3137 is lower, indicating that the code was in its second pass over the circular buffer. By using the wear leveling algorithm, each memory location was used once or twice.


The configuration values of the timing routine were changed to use a larger buffer after the test was run. Memory locations starting at 3501 were left uninitialized at 255 and show the maximum possible number for an unsigned long.


This throws the report off. One can go back and look by hand for the tell tale incrementing values followed by a lower value.


Here are the values for the larger buffer:


If we change that to match the size of the original bufffer:


Now the report runs right and finds the correct value:


58 minutes for a used 9V battery and 21.8 hours for a fresh set of AAA batteries. A fresh 9V battery should run about 8 hours.



And the standby runtime for the Mega Enigma on a fresh set of AAA batteries is a respectable 21 hours. Pressing keys and illuminating results in the lampfield will reduce that time, but code would have to be written to simulate keypresses and illuminate results.

 Now the question is, how long will the device run on a fresh set of AA batteries. The bigger the batteries, the longer the runtime...

How to put a battery compartment inside a laser cut enclosure.


Designing the battery compartment:


A template with all the pieces for an AAA battery holder.


An AA battery holder.


The laser cut files for an enclosure:


How the battery compartment looks like 














A hex nut piece was used as the first one to allow a small piece of plastic to keep the screws captive in the lid. The actual hex nut is sandwiched further down the stack in between two pieces with small holes.








coupled with a 9V plug, a device can be powered by the built in bateries or an external 9V battery.


A two way power switch selects between the internal and external power sources. Selecting the external source when there is nothing connected or the internal source when the battery box is empty turns off the machine.


Download the design files here:





Sunday, December 1, 2019

Friday, October 25, 2019

Get your head out of the Cloud(s) and design complex shapes PCB using Free and Open Source Tools

This post will show how to use the CAD program Sketchup to design an arbitrarily complex PCB shape that will be post processed with Inkscape so that Fritzing will accept it as a board outline and produce Gerber files that can be sent to a PCB Fab for production.

The 2019 Saintcon Cybersecurity Conference Badge is an Enigma Machine.


https://www.saintcon.org/2019/content/list/?type=presentations

The badges can be interconnected and form a circle in the shape of an Enigma Machine Rotor Wheel when 26 of them are put together.


We are currently designing a new Universal Enigma Machine Simulator.

https://hackaday.io/project/165559-at-mega-enigma-a-2560-pro-mini-enigma-simulator

Let's design a new PCB shape for this project. Fritzing accepts specially designed SVG files as PCB outlines. We need a way to design the SVG files first.

Sketchup is a 2-D and 3-D capable CAD program that's easy to use and can produce dimensionally accurate designs ready for laser cutting or 3D printing.

Sketchup has recently stopped updating the downloadable version and gone to the cloud. The free cloud version does not support exporting to SVG or downloading from the Extensions Warehouse.

Been using Sketchup to design enclosures for a while


Once an enclosure is designed and the finger joints drawn, the faces are selected, exported to SVG and placed in a Ponoko template for laser cutting in 3mm Birch Plywood.

https://www.ponoko.com/design-your-own/products/laser-cut-enclosure-for-arduino-enigma-simulator-with-engraved-enigma-logo--12132


Recently I have started using Sketchup to design objects for 3D printing as well.
https://www.thingiverse.com/arduinoenigma/designs


The goal is to make a new PCB Shape for this. The dimensions of the rectangle are 139mm by 171mm.


This post expands upon a previous one showing how to do a custom shape using Inkscape and Fritzing. First, Inkscape is used to generate an SVG file with three layers (board, silkscreen, silkscreen0). Fritzing will use this SVG file as the PCB outline.

https://hackaday.io/project/91895-sinclair-scientific-calculator-emulator/log/144392-how-to-design-a-custom-pcb-shape-for-fritzing-no-more-sharp-corners

Let's get started...

1:

Use the circle tool to draw a 26 segment circle. Press C, type a number, then type S26 to select 26 segments and finally draw the circle. The semicircular shape is drawn by first drawing a circle and then attaching two circle segments to the sides. The portions of the circle that are not needed are erased and we are left with a wavy contour.


 2:

The same technique is used to draw a 26 side circle, the width of the segment is set to 140mm by measuring it with the tape tool and then 140 is typed to resize the measurement to the desired value. The height of the PCB shape is set to 171mm. Then the width of the top of the shape is measured and the wavy shape in step 1 is resized by using the tape tool and copied and pasted to this file.

The bottom of the shape is flat but it can be made into a semi-circle by selecting the circle and specifying that it will have 96 segments instead of 26.


3:

Here is the final shape. The width at the bottom is 140 mm and the height of the rectangle is 171mm.


4:

Using an export plugin, the shape is saved as an SVG file.


5:

Open Inkscape and load the SVG file generated in the step before.


6:

Go to File-> Document Properties and click on Resize Page to Drawing or Selection. This step can be omitted.


7:

Using the Fill and Stroke tool, color the inside of the PCB. Any color is fine. Select something easy on the eyes. The PCB is rotated as well. (Rotating the PCB is also optional, it can be done at the end in Fritizng). Add three layers, name them "board", "silkscreen" and "silkscreen0". These names are for display only, the file will need to be edited to locate the XML "id" property and set it to match the display names.

 8:

Fritzing does not use the XML label property. It needs the ID property set. For that we need to edit the XML that makes the SVG file and change the layer ID properties.

Go to Edit->XML Editor, or press CTRL+SHIFT+X

Look for a line that says  inkscape:label="board", click on it.

Click on the "id" attribute on the right, click below the 'Set' button and type "board" without quotation marks and then click on the "Set" button.


9:

Repeat for "silkscreen" and "silkscreen0" The layer attributes should now be as shown below.


10:

Open Fritzing, Click on the PCB tab, click on the default PCB and on the Inspector window, click the "load image file" button.


11:

Navigate to where you saved the Inkscape SVG file and select it.


12:

A warning dialog will be shown, click OK and the PCB should be displayed. If it is sideways, click on "rotation" on the Inspector window and set it to -90


13:

An existing design is copied from another file into this. Notice that the shape of the PCB is accurately dimensioned.


14:

Rearrange any parts, save the file and export for production, select "Extended Gerber..."


15:

I prefer the look of tented vias, covering with soldermask the plated holes that connect traces in different layers.

This article shows the difference between tented and exposed vias.

https://hackaday.io/project/91895-sinclair-scientific-calculator-emulator/log/123664-12252017-finished-routing-the-board-and-submited-for-production

The steps:

-Save Work
-File->Export->For Production->Extended Gerber, create "tented" folder
-Routing->Select All Vias
-Press Delete key
-Export Gerbers to no-vias folder
-File->Revert

-Copy maskTop and maskBottom, silkTop and silkBottom files from no-vias to tented folder



16:

The mask and silkscreen files from the no-vias folder are copied to the vias-folder. This will ensure that the vias are covered with soldermask and if text is drawn above them, the silkscreen will show.


17:

The Gerber files are put together in one ZIP file and uploaded to OSHPark.com

And it is a fail. Instead of a purple board, we get a white one. The contour is open. Time to find where.


18:

Finish the import process at OSHPark, save the defective board and click on the board image, look for discontinuities in the outline. Here we have found one.


19:

Go to Sketchup and add lines in the problem area, delete any doubled up lines and repeat from step 4. This step might be difficult. Sketchup may decide that the contour is no longer closed even though it appears so. Keep adding lines and deleting doubled up lines until the contour closes again.

When repeating the setup process in Inkscape, this time the shape was not rotated and the document was not resized (steps 5-6). Instead the PCB was rotated -90 degrees in Fritzing.


20:

Repeat the Gerber export process and inport to OSHPark.

Success. It took a couple of tries, but finally we are rewarded with a purple board.

 

Finish the import process and then click on the board, make sure things look ok.




Here is an example of a 3D printed design being turned into a PCB. We will start with this 2-D Kokopelli figure and follow all the steps in this write-up.


And we get rewarded with a white board, another failure. Click on the board image and look for discontinuities in the outline.


The discontinuity was found in the lower arm elbow.


Going back to Sketchup, a circle with more segments was added to the lower elbow and the import steps repeated. This time we get rewarded with a properly rendered board.

This board will not manufacture 100% as drawn given the limitations of the routing bit used to cut the outline of the board. Sharp inner corners like the one where the lower arm touches the body and the flute will have a rounded edge.


Future work: