Showing posts with label PanelOne. Show all posts
Showing posts with label PanelOne. Show all posts

Monday, 20 October 2014

PanelOne on Sanguinololu

The PanelOne LCD display and control panel was originally designed for RAMPS1.4, and that is still the most sensible way to use it as it uses two 2x5 IDC cables that are readily available. The PanelOne circuit board is designed to work with 3.3V and 5V electronics and this weekend I tested it with Sanguinololu (effectively going full circle back to the original Panelolu - just a lot easier to put together and use!)



This works fine, although you do need to be careful to plug the pins in correctly:



The correct pins for Sanguinololu are:

Wire number    PanelOne             Sanguinololu
                         Aux2
1                       5V                         5V
2                       GND                     GND
3                       EN B                     Rx1
4                       EN A                     Tx1
5                       LCD DB7              A4
6                       LCD RS                PWM
7                       LCD DB6              A3
8                       LCD E                  SDA
9                       LCD DB5              A2
10                     LCD DB4              A1
                         Aux3
1 Not Connected
2 Not Connected
3                       CS                        A0
4                       CLK                      SCK
5                       DO                        MOSI
6                       DI                          MISO
7                       EN SW                  SCL
8                       VCC                      5V
9 Not Connected
10 Not Connected

This blog post has a good image of the location of each pin on the Sanguinololu, re-posted below:

The IDC cables are numbered with wire 1 being the red coloured wire.

This will work out the box with the T3P3 version of Marlin by enabling #SDSUPPORT and #ULTIMAKERCONTROLLER in configuration.h

The process followed can be adapted to use the PanelOne on any electronics that runs Marlin and has enough free pins. Do let me know if you get it working on another board!







Friday, 22 August 2014

Arduino based IDC cable tester

We use IDC terminated ribbon cables for the PanelOne LCD controller that we use in our Mini Kossel 3D Printer kits. Its a slow process to test these cables by confirming that the LCD, SD card, encoder etc all work so I looked for an IDC ribbon cable tester. I found a few online but they ran to ridiculous prices (~£250+) so decided to make one using an Arduino Mega and some strip board:


As can be seen there has been no time wasted on making it look pretty, in fact it is probably the ugliest circuit I have made, ever, however it works and tests cables!

Stripboard IDC cable tester circuit - hot glue used to protect questionable soldering

The circuit schematic includes the connections for a PanelOne as I had a prototype board that was no longer being used, however any 20x4 LCD screen and push switch would work.


It uses the internal pullup resistors on the arduino pins so no external components are required other than the connecting wires and headers.

I wrote a simple Arduino sketch to check the cable and display the results. It finds open and crossed wires:

Arduino Circuit Tester - Start Screen

Arduino Circuit Tester - Open Circuit

Arduino Circuit Tester - Crossed wires (plug on backwards)

Arduino Circuit Tester - Good cable
The next step will be to make a circuit tester for the 50 way Duet-Duex4 expansion header cables however that would require 100 pins which is more than is available on the Mega.... I2C port expanders here we come! Also I think a PCB will be required as 100 wires on stripboard would take far too long.

As usual its all open hardware and software - available on the Think3dPrint3d Github.

I hope someone finds this useful and I would be interested to see if anyone else tries this!


Monday, 18 August 2014

PanelOne LCD screen for 3.3V and 5V electronics

Following on from this post on using the PanelOne LCD screen with the Duet at 3.3V, this post shows the modified design for the PanelOne that uses a 3.3V LCD.

While I managed to get a specific LCD work with both 3.3V and 5V, it was an edge case. It was not transferable to other LCD manufacturer's displays and it may have shortened the display's life. To that end I changed the specifications to use a 3.3V LCD. This display is actually a 5V display with a voltage inverter and divider on board that provides -2V to VO.



PanelOne circuit board view from the back with 3.3V LCD


Close up of the -2V circuit on LCD

This -2V means that with 3.3V supplied, the voltage drop is 5V which the display driver chip needs to run the LCD pixels.

For reference here is the Schematic again, now on version 2.1, with the -2V on board annotated:



So the contrast pot on the PanelOne circuit board is acting as a variable resistor setting VO between 0 and -2V, and hence the contrast between "off" and "on" pixels on the LCD.

For a purely 3.3V use there would be no requirement for the 5V-3.3V LDO and the 4050 level shifter for the SD card. However, I want to be able to use this on both 3.3V and 5V logic with minimal changes. For the display to work with 5V we have two options. The first is to use a 5V display rather than 3.3V, thus requiring only 1 PanelOne circuit board design. Alternatively we could use the same 3.3V display and disable the -2V on VO. The simplest way to do this is to remove the resistor R6:


Close up of the -2V circuit disable with R6 removed

I have left it soldered on at one end so it's easy to switch back and forth. Obviously a switch would be even better (cue email to LCD manufacturer to consider updating their design).

This design is now proven on both 5V (RAMPS) and 3.3V (Duet etc) electronics:

PanelOne 2.1 with RAMPS

PanelOne 2.1 with Duet

The connection to the Duet is still made with single pin connectors and the RepRap Firmware does not yet support an LCD screen although the community (and me!) are working on it.

As always our designs are open hardware (CERN OHL 1.2) - the latest KiCAD files are available on our Github. In addition the updated case is also shared in STL and OpenSCAD on github.

We will be using the PanelOne v 2.1 circuit board in our Kossel Mini kits once our current stocks of 5V-only PanelOne boards are used up. In addition we have listed variations on the webstore, where you can choose the 5V only version or the 3.3V version (which you can adapt to 5V using the resistor de-soldering method outlined above).


Saturday, 19 July 2014

Duet, 20x4 LCD screen and SD card.

Although the Duet communicates over Wifi and I can connect to it with a web browser on my phone, I still get many requests for a LCD based controller. I agree that being able to use a simple controller for quick, common functions is a good idea, things like homing the printer, preheating, starting a print etc. Think3dPrint3d have been providing controllers for older electronics that do this since we started, first with the Panelolu then with the Panelolu2 so it's time to port this to the Duet.

I decided to keep it simple to start with, so rather than get the Panelolu2 working, which would require I2C and headaches with 3.3V and 5V logic, I started with the PanelOne, a very basic LCD, Encoder, SD card combination which we are using on our Kossel Mini Kits.

Using a 5V LCD with 3.3V Microprocessor

This was the first hurdle to overcome. The HD44780 standard that these character LCD displays work on states 2.7 to 5V should work fine for the logic signals, however the LCD screens incorporating these chips are a lot more restrictive: 4.8-5.2V for the logic signals. Given the conflicting information I decided to modify a PanelOne prototype board by hand and give it a go. The key is to keep the logic signals separate from the backlight voltages. The schematic is below:



The major change is the addition of the "VCC" power into pin 2 of the LCD from pin 8 of header P1. Previously this was a straight 5V, now this should be able to be either 5V or 3.3V depending on the logic of the Microprocessor we are interfacing with. I connected this up and edited the "Hello World" sketch within Arduino 1.5.7 (1.5.6 r2 works as well) to use the following pin definitions:
/*
                            Arduino pin number  Duet Pin Name  Expansion header pin
 * LCD RS pin to digital pin D67                 PB16          (32)
 * LCD Enable pin to digital D23                 PA14          (10)
 * LCD D4 pin to digital pin D19                 PA10 RXD0     (14)
 * LCD D5 pin to digital pin D18                 PA11 TXD0     (13)
 * LCD D6 pin to digital pin D17                 PA12 RXD1     (12)
 * LCD D7 pin to digital pin D16                 PA13 TXD1     (11)
*/
LiquidCrystal lcd(67, 23, 19, 18, 17, 16);

Happily this worked!




I tested this with two other LCDs (old generic ones off eBay) and it worked with them as well. However as it's outside the guidelines of the LCD manufacturer's datasheets there is no guarantee that all types of HD44780 character LCDS will work in the same way.

Reading an SD card over SPI

The Duet's build in SD card supports SD2.0 and uses a 4 bit HSMCI interface. However it is often convenient to use an SD card reader mounted next to the screen, so I want to support SD over SPI which is how older 3D printer electronics and hardware interface with SD cards. The Arduino environment has a simple SPI SD library that worked straight away. The only customisation required is to make sure SD.Begin() uses the correct CS pin:

SD.begin(77);

For this example I used the SPI0_NPCS0 pin which is arduino digital pin 77. I combined the listfiles example sketch with the LCD display to list the first 4 files on a SD card:






The code (an adaptation of the listfiles example sketch):


#include <SPI.h>
#include <SD.h>
#include <LiquidCrystal.h>

File root;
// initialize the library with the numbers of the interface pins

LiquidCrystal lcd(67, 23, 19, 18, 17, 16); //RS,E,D4,D5,D6,D7

void setup()
{
  lcd.begin(20, 4);
  lcd.print("Reading Files...");
  delay(2000); //delay or else the message will not be displayed

  if (!SD.begin(77)) {
    lcd.clear();
    lcd.print("initialization");
    lcd.setCursor(0,1);
    lcd.print("failed!");
    return;
  }
   lcd.clear();
   lcd.print("initialization done");
   delay(2000); //delay or else the message will not be displayed
   lcd.clear();
   lcd.print("listing 4 files");
   delay(2000); //delay or else the message will not be displayed
   root = SD.open("/");
   lcd.clear();
   printDirectory(root, 0);
}

void printDirectory(File dir, int numTabs) {
  int row=0;
   while(true) {
     if(row>3) return;
     lcd.setCursor(0,row);
     File entry =  dir.openNextFile();
     if (! entry) {// no more files
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       lcd.print(' ');
     }
     lcd.print(entry.name());
     if (entry.isDirectory()) {
       lcd.print("/");
       printDirectory(entry, numTabs+1);
       row++;
     } else {
       // files have sizes, directories do not
       lcd.print("  ");
       lcd.print(entry.size(), DEC);
       row++;
     }
     entry.close();
   }

}

This sketch, and the adapted Kicad schematic are all on the Think3dPrint3d github.

Next...

I will test more LCD screens and hopefully will be able to get the next batch of PanelOnes compatible with both 3.3V and 5V.

The big job will be to port and adapt the Marlin menu system to RepRap Firmware. If anyone wants to assist with this project then drop me a line and I may be able to help with some hardware (duet board + LCD screen).

Sunday, 1 June 2014

Kossel Mini and More




Our Mini Kossel is a version of the excellent Kossel delta robot printer from Johann Rocholl, the designer of the original Rostock delta. It's very quick and easy to put together and relatively economical to source parts for. We have designed some additional parts and incorporated a number of variations from around the community. The changes we have made are described below and all the additional source files are available on Github (look in the T3P3 additions directory)

The Mini Kossel can be bought as a kit or assembled from www.think3dprint3d.com  There are 5 colours in stock or we will print you a set in any custom colour we can source and print. All our parts are printed in ABS on our Mendel90 Lasercut production printers which continue to churn out excellent-quality parts every day after almost a year in service.



Linear Rails v Rollers


The initial Kossel design used linear rails


Picture (c) hiwin.com
These are great but add significantly to the cost. Using rollers on the aluminium extrusions themselves has been suggested in a number of places:

http://www.electronhacks.com/2013/12/kossel-mini-3d-printer-vertical-movement-tutorial/

http://www.thingiverse.com/thing:308369

and this comparison here: http://www.builda3dprinter.eu/rails-wheels/.

These convinced us to try the roller based option. As we are using Mitsumi aluminium extrusions we got Delrin rollers precision machined:



After many hundred of hours printing the bearings and extrusions are not showing visible wear. The only lubrication we have used is a spray of light oil containing PTFE (for example GT85). It is very simple to tighten the adjusting capscrew to adjust the pre-load and take up any slack if they do wear.

Johann is looking into using recirculating Delrin balls directly on the extrusion as well - well worth following up as and when time permits. Delrin balls are quite pricey, though, but it would be awesome if Airsoft BB pellets turned out to work well. The best carriage for these turned out to be Haydn Huntley's.


RepRapPro mini extruder


This extruder has been proven over many thousands of hours, both on RepRapPro's Mendel and Huxley printers and on our Mendel90 Lasercut multi extruder machine.



We modified this slightly to use easily obtainable pushfit bowden fittings and made a our own version of the quick and simple zip tie mount to fit to the extrusion:






Power and electronics mountings

To keep the kit as simple and user friendly as possible we designed a USB and power plug plate:


That provides a neat interface with the RAMPS in the base of the printer. The non-heated bed version uses a single 5 amp laptop style power supply. We are investigating options for the heated bed version but one being considered is an extension of this plate with another plug for a heated bed power supply. The RAMPS is mounted on another simple plate:


The picture also shows some simple tabs to keep a round glass mirror plate fixed securely using M3 penny washers.



Filament management

A reel holder and filament guide complete the kit:


Build Manual

We have written a comprehensive Kossel Mini Assembly Manual for the kit which we hope will become a useful resource for all. We would really welcome feedback on the manual and suggestions for additional information to add. 

Prints

One of the Mini Kossel beta testers did these prints of the EggO egg "thrones" by mageli which are awesome. 




PanelOne LCD

Following on from the case design tutorial in SCAD here is more information of the PanelOne, a simple LCD controller for RAMPS. It is optimised for those who want to rout/etch a single sided PCB with only through-hole components. It also uses widely-available 10-way IDC ribbon cables.




The more fiddly elements of the SD card socket and logic level converter are left to an optional, and generally available, daughter board such as this one from adafruit:


image from adafruit.com
or this one:
image from hobbytonics.co.uk

The circuit board itself is designed in KiCAD as a single sided board, and was originally designed for Sumpod who commissioned us to design a board that could be routed on a PCB mill and fitted the dimensions of their printer enclosure.



In keeping with the simplicity of the design there is no adaptor board required at the RAMPS end as the pinouts are arranged to match with the AUX2 and AUX3 headers.



The complete KiCad files for the PanelOne are available on github.

Coming Soon

Watch this space... we are working on adding a heated bed and an interesting twist on multiple extruders!

Friday, 25 April 2014

Using OpenSCAD to design a basic LCD enclosure

Regular readers will be aware I am a big fan of using scripted CAD, specifically OpenSCAD, as a design tool. I have gone into my reasoning before, which I won't repeat now. This is a further worked example showing the steps I took to design a case for a basic LCD+Click encoder controller for a 3d printer. This posts will try not to repeat too much ground covered in my previous OpenSCAD "How To": the OpenSCAD manual will help following along.

As always this is Open Source Hardware so the OpenSCAD source and supporting control knob file is shared on GitHub.


The electronics to encase


The PanelOne is a simple back board for a 20x4 character LCD with a encoder, a SD card board and brightness and contrast pots. I will go into the rationale and design of it in another post.



The aim for the case is to be quick and easy to print and use the the minimum of additional screws and other fixings.

Step 1 - Measurements


First step is to take measurements of the dimensions of the electronics - these can be taken from the CAD files if you have them:


This shows using the dimension function in KiCAD, although you can read the co-ordinates directly. The other, and my preferred, option is to take direct measurements:


This allows for the effect of the assembly processes to be taken into account easily.

Step 2 - Model the Electronics


Depending on how complex a case you are making, this step can be very simple or very complex. For a great example of how complex a circuit model model can be, check out UrielGuy's model of the Sanguinololu electronics




In this case I am going to keep it simple.

Start by assigning the measurements to variables - you will thank yourself many times over as you come to reuse or modify these.:

clearance=0.8;
wall_width=1.6; //minimum wall width //should be a multiple of your extruded dia
layer_height=0.2;

//LCD screen
lcd_scrn_x=99;
lcd_scrn_y=40.5;
lcd_scrn_z=9.4;

lcd_board_x=99;
lcd_board_y=61;
lcd_board_z=1.6; //does not include metal tabs on base

lcd_hole_d=3.4;
lcd_hole_offset=(lcd_hole_d/2)+1;

//board edge to center of first connector hole
lcd_connect_x=10.2;
lcd_connect_y=58.4;

//PanelOne circuit board
pl_x=136;
pl_y=lcd_board_y;
pl_z=4; //excluding click Encoder and SD card and cable headers, but including the soldered bottoms of the through hole connectors
pl_mounting_hole_dia=3.4;
pl_mounting_hole_x=133.6;
pl_mounting_hole1_y=3.4; //only bothering with 2 holes at this point
pl_mounting_hole2_y=58.4;

//rotary encoder
click_encoder_x=13.2;
click_encoder_y=12.6;
click_encoder_z=6;
click_encoder_shaft_dia=6.9+clearance;
click_encoder_shaft_h=12.2;
click_encoder_knob_dia=24;
click_encoder_offset_x=112.2;
click_encoder_offset_y=30.8;


//contrast and brightness holes
cb_dia=4; //hole diameter for adjustment screw
cb_h=15;
con_offset_x=107.2;
con_offset_y=16.1;
con_offset_z=pl_z;
bri_offset_x=117.1;
bri_offset_y=16.0;
bri_offset_z=con_offset_z;

//headers
//lcd connection header
lcd_h_x=(16*2.54)+2.54;
lcd_h_y=2.54;
lcd_h_z=3; //this is the gap between the circuit board caused by the plastic spaces on 2.54mm headers
lcd_h_offset_x=lcd_connect_x;
lcd_h_offset_y=lcd_connect_y;
lcd_h_offset_z=pl_z;

//IDC headers, use the clearance required for the plug
//these are much bigger on z than the actual headers for clearance
idc_h_x=16; //not all will be within case
idc_h_y=14+clearance;
idc_h_z=pl_z+click_encoder_z;
idc1_offset_x=128.4;
idc1_offset_y=20.5-clearance/2;
idc1_offset_z=-wall_width;
idc2_offset_x=idc1_offset_x;
idc2_offset_y=39.6-clearance/2;
idc2_offset_z=idc1_offset_z;

//SD card slot
SD_slot_x=24.5+clearance; //wider for clearance
SD_slot_y=29.5;
SD_slot_z=4;
SD_slot_offset_x=100.5-clearance/2;
SD_slot_offset_y=39.5;
SD_slot_offset_z=pl_z;

//case variables
shell_split_z = pl_z+SD_slot_z; //board split in the top of the slots
shell_width=wall_width+clearance;

shell_top = pl_z+click_encoder_z+2;

Then I write a number of small functions to draw up the components:

module LCD_assembly() {
    translate([0,0,lcd_h_offset_z+lcd_h_z])
        lcd();
        pl_board();
   //lcd connection header
    color("black")
        translate([lcd_h_offset_x,lcd_h_offset_y,lcd_h_offset_z])
            cube([lcd_h_x,lcd_h_y,lcd_h_z]);
}

//LCD screen
module lcd() {
    difference(){
        union(){
            color("OliveDrab")
                translate([0,0,0])
                    cube([lcd_board_x,lcd_board_y,lcd_board_z]);
            color("DarkSlateGray")
                translate([(lcd_board_x-lcd_scrn_x)/2,(lcd_board_y-lcd_scrn_y)/2,lcd_board_z])
                    cube([lcd_scrn_x,lcd_scrn_y,lcd_scrn_z]);
        }
        for(i=[lcd_hole_offset,lcd_board_x-lcd_hole_offset]){
            for(j=[lcd_hole_offset,lcd_board_y-lcd_hole_offset]){
                translate([i,j,lcd_board_z])
                    cylinder(r=lcd_hole_d/2,h=lcd_board_z+3,$fn=12,center=true);
            }
        }
    }
}

//PanelOne circuit board simplified
module pl_board() {
    difference(){
        union(){
            color("lightgreen")cube([pl_x,pl_y,pl_z]);
            //click encoder
            color("darkgrey"){
                translate([click_encoder_offset_x,click_encoder_offset_y,pl_z+(click_encoder_z)/2])
                    cube([click_encoder_x,click_encoder_y,click_encoder_z],center=true);
                translate([click_encoder_offset_x,click_encoder_offset_y,pl_z+click_encoder_z+(click_encoder_shaft_h)/2])
                    cylinder(r=click_encoder_shaft_dia/2,h=click_encoder_shaft_h,center=true);
            //contrast and brightness pots
                  translate([con_offset_x,con_offset_y,con_offset_z+cb_h/2])
                    cylinder(r=cb_dia/2,h=cb_h,center=true);
                  translate([bri_offset_x,bri_offset_y,bri_offset_z+cb_h/2])
                    cylinder(r=cb_dia/2,h=cb_h,center=true);
            }        
        }
        translate([-0.1,-0.1,-0.1]){
            cube([93,45,pl_z+2]);
            cube([6,lcd_board_y+1,pl_z+2]);
        }
        //mounting holes
        translate([pl_mounting_hole_x,pl_mounting_hole1_y,(pl_z+3)/2])
            cylinder(r=pl_mounting_hole_dia/2,h=pl_z+3,center=true);
        translate([pl_mounting_hole_x,pl_mounting_hole2_y,(pl_z+3)/2])
            cylinder(r=pl_mounting_hole_dia/2,h=pl_z+3,center=true);
    }
    //SD board 
    color("lightblue")    
        translate([SD_slot_offset_x,SD_slot_offset_y,SD_slot_offset_z]) 
            cube([SD_slot_x,SD_slot_y,SD_slot_z]);
   //IDC headers
    color("darkgrey"){
        translate([idc1_offset_x,idc1_offset_y,idc1_offset_z])
            cube([idc_h_x,idc_h_y,idc_h_z]);
        translate([idc2_offset_x,idc2_offset_y,idc2_offset_z])
            cube([idc_h_x,idc_h_y,idc_h_z]);
    }
}



It is a good idea to split down the design into logical blocks - these can be reused. The LCD module is re-used from the Panelolu2 case design for example.

I used the color function within OpenSCAD to make this render easier to view:

Step 3 - The Case


The case will be a simple design with back and front halves, along with a knob for the click encoder. It will be held together with M3 screws. A mounting method will be discussed in a later post.

The back and front halves are very simple to code, since the hard work has already been done in defining the electronics which is used to "cut" the holes required in the case.

module case_screw_holes(nut_trap=false,z_height=0, dia=lcd_hole_d) {
for(i=[lcd_hole_offset,pl_mounting_hole_x])
for(j=[lcd_hole_offset,pl_mounting_hole2_y]){
if (nut_trap) {
translate([i,j,z_height])
cylinder(r=dia/2, h=shell_width*2, $fn=fn);
translate([i,j,z_height])
cylinder(r=m3_nut_diameter_bigger/2+layer_height*2, h=shell_width, $fn=6);
} else {
translate([i,j,z_height])
cylinder(r=dia/2,h=shell_width*2+30,$fn=12,center=true);
}
}


}

module back() {
    difference(){
        translate([-shell_width,-shell_width,-shell_width])
            cube([pl_x+shell_width*2,pl_y+shell_width*2,shell_split_z+shell_width]);
        translate([-clearance,-clearance,-clearance])
            cube([pl_x+clearance*2,pl_y+clearance*2,shell_split_z+clearance+0.01]);
        LCD_assembly();
        case_screw_holes(false,-shell_width);
    }
    //support pillar
    translate([6,6,0])
        difference(){
            cube([10,10,pl_z+lcd_h_z]);
            translate([wall_width,wall_width,0])
            cube([10-wall_width*2,10-wall_width*2,pl_z+lcd_h_z+0.1]);
        }
    
}



module front() {
    difference(){
        translate([-shell_width,-shell_width,shell_split_z])
            cube([pl_w+shell_width*2,pl_y+shell_width*2,shell_top-shell_split_z+shell_width]);
        translate([-clearance,-clearance,shell_split_z-0.01])
            cube([pl_w+clearance*2,pl_y+clearance*2,shell_top-shell_split_z+clearance]);
        LCD_assembly();
        case_screw_holes(false,shell_top+shell_width);
    }
}


The difference() function used in the code above subtracts a cube that is "shell_width" - "clearance" from the overall front or back shell. It then subtracts the LCD_assembly and the case holes.  The following two pictures (with elements made transparent/hidden) helps to illustrate the process.




Step 4 - Tweak


The great thing with rapid prototyping is the ability to quickly test out designs and make improvements. The first rough print had a couple of issues:


support for the LCD needed

clearance for the IDC connectors needs moving up

Overall the following issues were noted:

  • The holes for the IDC plugs for the cables need to be wider and higher up in the case, easiest to replace with a single cutout.
  • The box spacer used as a support in the back interfered with the back of the LCD
  • To hold the board more rigidly some supports are required - the corners are the easiest place for these.

Fixes:


Change the IDC header dimensions, only one "header" needed in the model now:

//IDC headers, use the clearance required for the plug
//these are much bigger on z than the actual headers for clearance
idc_y_x=16; //not all will be within case
idc_y_y=37.9;
idc_y_z=6.39+2.5;
idc1_offset_x=128.4;
idc1_offset_y=18.1;

idc1_offset_z=1.61;



Remove the box spacer and add supports to the front and back:

module back() {
    side=8; //for the supports
    difference(){
        union(){
            difference(){
                translate([-shell_width,-shell_width,-shell_width])
                    cube([pl_x+shell_width*2,pl_y+shell_width*2,shell_split_z+shell_width]);
                translate([-clearance,-clearance,-clearance])
                    cube([pl_x+clearance*2,pl_y+clearance*2,shell_split_z+clearance+0.01]);
                LCD_assembly();
            }
            //corner supports
            for(i=[-wall_width,pl_y-side+wall_width]){
                translate([-wall_width,i,-shell_width])
                    cube([side,side,8.75]);
                translate([pl_x-side+wall_width,i,-shell_width])
                    cube([side,side,4.35]);
            }
            //additional support
            translate([lcd_board_x-side,-wall_width,-shell_width])
                cube([side,side/2,8.75]);
        }
        case_screw_holes(false,0);
    }
}

  

module front() {
    side=8; //for the supports
    difference(){
        union(){
            difference(){
                translate([-shell_width,-shell_width,shell_split_z])
                    cube([pl_x+shell_width*2,pl_y+shell_width*2,shell_top-shell_split_z +shell_width]);
                translate([-clearance,-clearance,shell_split_z-0.01])
                    cube([pl_x+clearance*2,pl_y+clearance*2,shell_top-shell_split_z +clearance]);
                LCD_assembly();
            }
            //corner supports
            for(i=[-wall_width,pl_x-side+wall_width])
                for(j=[-wall_width,pl_y-side+wall_width]){
                    translate([i,j,shell_split_z])
                        cube([side,side,shell_top-shell_split_z+wall_width]);
                }
            //additional supports
            for(i=[-wall_width,pl_y-side/2+wall_width]){
                translate([lcd_board_x-side,i,shell_split_z])
                cube([side,side/2,shell_top-shell_split_z+wall_width]);
            }
        }
        case_screw_holes(false,shell_top+shell_width);
    }
}


The final case:


Step 5 - Optional Extras


For models I use often or that go through many iterations where I want to quickly change between different parts it makes sense to simplify the selection of what part of the model to display. At the top of the scad file I have:

///////////////////////////////////////////////////////////
//front, back or Assembly
///////////////////////////////////////////////////////////
side=2; //1 = front, -1 = back 2=printing layout -2 Electronics module 0=assembly model
///////////////////////////////////////////////////////////

This then determines what is rendered using a list of if statements used because, annoyingly, OpenSCAD does not appear to support a "switch" statement.

///////////////////////////////////////////////////////////////////////////////////////
// front
if (side==1)
{
    front();
}
// back
else if(side==-1)
{
    back();
}
//Printing plate
else if(side==2)
{
    translate([shell_width,pl_y*2+shell_width*4,shell_top+shell_width])
        rotate([180,0,0])
            front();
    translate([shell_width,shell_width,shell_width])
        back();
    translate([pl_y*0.5,pl_y*1.5+shell_width*2,shell_width])
    knob_assembly(click_encoder_knob_dia/2);
}
//Electronics
else if(side==-2)
{
    LCD_assembly();
}
//assembly
else
{
    back();
    front();
    LCD_assembly();
 translate([click_encoder_offset_x,click_encoder_offset_y,wall_width+ click_encoder_shaft_y+click_encoder_z-2])
        knob_assembly(click_encoder_knob_dia/2);
}
///////////////////////////////////////////////////////////////////////////////////////

Thus changing one number allows you pick the render you want:




That's all for now - I hope to get a blog post out about the PanelOne itself soon.