Best OS to Make an Old Chromebook Useful Again

I have this old HP Chromebook 14 which has only 2GB of RAM.  It’s so old that google stopped supporting it (which is ridiculous as it just makes people either A. use an insecure device or B. throw it away.  It is incredibly irresponsible and wasteful for google to create “disposable” computers like this…  Anyway I had to get some further use out of this thing to feel better about the situation.

After first attempting to use Crouton to turn an old and no longer supported chromebook into a dedicated octoprint server and laser cutter machine, I gave up and decided to go a different route. Crouton allows you to run linux AND chromeOS which is a safer option and easily reversible if something goes wrong. The issue is that my chromebook was so old that google no longer supported it anymore.  Due to the limitations of not being able to access the camera for octoprint, and Beam Studio (for my FLUX Beamo laser cutter) didn’t want to connect to my laser I moved on. I’ll instead wipe the machine and give it to someone who can use it.

After trying different versions of smaller linux distros like xubuntu, Lubuntu and even minimumOS of ubuntu (only 64MB!) I had issues installing all of them. All the *buntu flavors were too big for my 2GB RAM so it didn’t even boot up.  The minimumOS was going to be a lot of work if it worked to setup and install everything I’d want if it worked, but I had issues using a bad iso burning software that caused issues with this one. Luckily I kept looking and found the absolute best chromeOS replacement available.

I completely wiped ChromeOS and installed GalliumOS on the HP14 Chromebook (white chromebook) using this step-by-step guide. I have to say that it is by far the best solution and I wish I had done so much earlier. First download and burn the ISO to a USB drive. The only change I’d recommend is to use Balena etcher to burn the ISO to the USB flash drive.

Now, every time you boot up, it gives you an OS verification error (Yellow icon). At this point you must hit “Ctrl+1”  within 5 seconds otherwise it’ll give you a red icon error  and you’ll just need to restart again.

Default Launcher bar:

While I typically don’t mind this bar, the person I was giving this to would prefer it to be gone. It doesn’t stack multiple windows into one icon like modern OS bars do. Since I can’t remove it, I moved it to the top. It is hard to find the settings for this. You must click the “start” icon (which is called the “whisker” menu) and select the “Settings” icon at the top next to the power button (NOT the settings button in the right menu…). Then you can find the main settings for everything.

Right click this bar and go to properties to edit some stuff too if you want.

I wanted to setup the whiskerbar to autohide and be at the top of the screen (like on a mac). So from the settings app, I chose “Panel” and unlocked the bar. I then dragged it to the top and locked it again. Keep this settings window open as we’ll use it again in a sec…

New Mac-like Launcher Dock:

I installed Plank to build a mac-like dock.

sudo apt-get install plank

To add the trash can to this new dock, you need to ctrl+click the plank bar to access its options then drag the trashcan to the bar.  If you add a “docklet” like the trash can or taskmanager and want to remove them later, simply drag it off the bar onto the desktop and it’ll disappear.

When I first ran this, clicking the trash can opened the audio player for some dumb reason. The fix was so stupid simple I would have never thought to do it… In the regular start menu (now at the top bar) go to settings > Preferred Applications > Utilities.  In file manager “Thunar” is selected but you should select “other” and then type “thunar”.  This does the trick.

Now go back in your settings menu of GalliumOS and select “Sessions and startup” then select the “Applications and startup” tab. You can then add “plank” as the command and it’ll autostart the plank docker bar on startup.

Login screen:

Be default it was using xscreensaver with a terrible interface.

Image via ubuntuBuzz

I installed light-dm instead which has a nicer and themable interface.This leads to a much more modern and sleep looking design.

Icons:

I installed numix icons, then you can set the icons by going to Whisker start menu–>the settings icon next to the log-out  and power icons. Select “Appearance”and select the “icons” task.

 

sudo apt-get install light-dm-gtk-greeter-settings

sudo apt-get remove xscreensaver

sudo apt-get install gnome-screensaver

 

Chrome Keyring constantly pops up error:

Each time I logged in and opened chrome, it’d pop up asking me to login to the keyring. That’s pretty annoying. So I found in multiple places online the suggestion to delete the keyring to reset it. This worked great!

Rm ~/.local/share/keyrings/login.keyring


Restart and it’ll ask you once, then never again.

Here’s an additional set of tips for what to do if you want to add more functionality.

RGB565 to RGB888 Color Conversion

While working with Charlotte Latin FabLab students this year, we came across an issue. Alex was using a camera module for her Arduino project (ArduCam) that gave RGB565 formatted pixel data but she needed to convert it to RGB888. Though there are tons of posts on stackExchange about how to do it, I couldn’t find a simplified broken-down explanation of how it works to point her to, so I decided to write one.

RGB565 means there are 5-bits of data for the Red component of the pixel, 6-bits for green and 5-bits for the blue.  It looks like this:
pixel value =
RED= R4, R3, R2, R1, R0,
GREEN= G5, G4, G3, G2, G1, G0,  
BLUE= B4, B3, B2, B1, B0

But Remember RGB565 is stored as two separate values (VL and VH from the example code for the camera we used), with the low value on the left and high value on the right.
VL = G2, G1, G0, B4, B3, B2, B1, B0     VH = R4, R3, R2, R1, R0, G5, G4, G3

Some clever bitmasking can strip out each component color and place them into individual variables. We’ll AND the bits of the values we want from VL and VH with ‘1’ or ‘0’ depending on which we want at a given time.

Of course this has to be done for each and every pixel, and she had 320 x 240 in her original image.

This is a simple nested for loop that already used in the example code to read the data from the camera

for (int i=0; i<240; i++){

  
   for (int j=0; j<320; j++){
  
    //Convert the RGB 565 to RGB 888 of the pixel in the bitmap and store it as PIXEL data type in the new larger array.

  
    //Step A convert to the new PIXELS format

  
    ///Step B scale from 565 to 888

  
    }//end for j

  
 }//end for i

STEP A: Convert the color to a new pixel format.

Based on some example code, it’s best to create a structure to contain the R, G and B values:

typedef struct { 
unsigned char blue; 
unsigned char green; 
unsigned char red; 
} PIXELS; 

Then we need a large array to store the pixels of the new image:

PIXELS bigPIXELS [12] [12]; //the resulting RGB888 picture pixels are stored here

Then you can convert each pixel by using logic operations and bit shifting.

/*Blue is the easiest to see how this works so we'll do it first.
  
 The values for Blue is stored in VL So for example if VL = 1011  0101( blue = 21 in decimal) 
 to get the blue values all alone, we can AND them with 1s and AND the green bits with 0s 
 leaving you with an 8-bit number with only the blue data in the right spot. The result 
 is: 0001  0101  or 21 in decimal. 
*/
  bigPIXELS [i][j].blue =    ( VL & 0b00011111 ) ; //0x1F
 
 

/*Red is only slightly more complicated. We first get bits for red alone, then shift them 
 to the decimal point The 0b11111000 gives you only red data as before, but the digits 
 aren't in the right place. 
 
 There are place-holding 0s that make the value of red too big: 
 For example is VH = 1101  0110  The value of red is 26 in decimal here. ANDing as before
 would give you only 1101  0000, but if we convert this number to decimal, it =208, which 
 isn't right at all. Shifting to the right by 3 (>>3) moves the red value down to the 
 decimal point and gives you 0001  1010 = 26 in decimal in 8-bits
*/
  
bigPIXELS [i][j].red =   ((VH & 0b11111000) >> 3); //0xF8
 

/*Green is the most complicated as it has components in each VL and VH so we'll AND the 
 bits with 1s and then shift them to the right places, then we need to OR them to the correct spot
  
 VL = G2, G1, G0, B4, B3, B2, B1, B0  so to get only green values
 */ 

// since we don't use this variable for anything else, we can just dump the result of this operation back into VL
 VL&= 0b11100000 ;  // 0xE0  

 // VH = R4, R3, R2, R1, R0, G5, G4, G3  so to get only green values  
 VH &= 0b00000111; //0x07
  
 //Now shift the bits to the right places and OR them together to glue them into one number
bigPIXELS [i][j].green =  (uint8_t(VL) >> 5) | (VH << 3); //Shift lower 3 bits in VL to the decimal point, and shift the upper 3-bits in VH to their correct positions.

Great! Now we have our RGB values by themselves, now let’s let them stretch their arms to take up the full 8-bits that’s now available to them.

Step B: Converting from one colorspace to another is simply a function of scaling. You’ve already done this a lot actually. Any time you’ve read an analog input, then used that to control an analog output on arduino you’ve done it. Imagine a knob on the Arduino’s analog input. Analog inputs can read values from 0-1023 (10-bits) where 100% is = 1023. Imagine a single red pixel as an LED on an analog output. It can only take values between 0 and 255 (8-bits) where 255 is 100% brightness of the LED.

You can do the same thing here. In a 5-bit number system, 100% is when all bits are 1’s so it is 11111. This needs to be converted to an 8-bit system where 100% is = 1111  1111.

You use Arduino’s map() function to map the values from one scale(0-1023) to the other (the LED’s 0-255), however this is very inefficient and slow.

Since you know what the numbers are going to be for the scaling calculation, and they won’t ever change you can pre-calculate them for your code. You’re scaling from 5-bits to 8-bits for red and blue which is 0xFF / 0x1F = 255 / 31 = 8. For green you start with 6-bits and convert to 8 which is 0xFF / 0x03 = 255 / 63 = 4.  You could multiply these hardcoded numbers to scale red *= 8; green *=4; blue*=8; however since these are powers of 2, there’s a trick to make this code faster. Simply bit shift left. For each bit you shift, it is equal to a power of two so the code would be red and blue << 3 and green << by 2.

//If you want to see the RGB 565 values print them here, or comment out if you don't need them
Serial.print(" RGB565 =");
Serial.write(bigPIXELS [i][j].red);
Serial.write(bigPIXELS [i][j].green);
Serial.write(bigPIXELS [i][j].blue);

bigPIXELS[i][j].blue = bigPIXELS[i][j].blue << 3;//blue and red were 5-bits

bigPIXELS[i][j].red=  bigPIXELS[i][j].red<<3;

bigPIXELS[i][j].green =  bigPIXELS[i][j].green <<2;//Remember that green has 6 pixels to begin with so it only shifts 2 places

Now you can do with these as you please. Add a BMP header and print them to the serial port to be able to view this BMP image on your computer.

Serial.print(" RGB888 R= ");
Serial.write(bigPIXELS [i][j].red);
Serial.write(bigPIXELS [i][j].green);
Serial.write(bigPIXELS [i][j].blue);

 

Cheapest and Fastest COVID-19 Face Shield

I’m working with some folks on a project to 3D print a ton of face shields for Charlotte hospitals during the COVID-19 crisis, but I figured there has to be a faster and cheaper way. I worked something out with parts I had in the garage and it costs pennies to make. it even adjusts so you can lift it up or lower it down over your face.

What you’ll need:

Drill a hole with a drill bit or a utility knife (drill with the knife by spinning it, don’t cu ta hole or it will tear and be weak)

It’s adjustable.

 

Make 3D Pictures with Our Free Web App

If you didn’t already know, Jess recently wrote a great book full of science experiments for parents and kids to do at home. If you haven’t heard about it, check it out here. All bias aside, it really is the best science experiments book I’ve ever read. The projects are really cool and engaging. This book is written for ages 8 to 12 but there are projects that you would enjoy at any age. Everything is explained in very easy to understand terms from double-pendulums and chaotic motion to making holograms by hand.

One of the really cool projects in the book is making your own 3D glasses with stuff laying around your house. I wrote a little app to help you play around with depth and perspective when drawing your own 3D images. Check out the examples below.  You can adjust the depth and lightness of each line you draw and you can actually edit lines you’ve previously drawn. Click here to play with the 3D anaglyph maker.

Here’s an example of the type of results you can get with the app. You can tell I am no artist… but you can draw with the mouse and adjust the depth and darkness of the lines, then export the image to your computer. Feel free to upload your pic to imgur and paste a link in the comments to show us what you create!

 

 

 

 

Digital Caliper Power Cable

The worse thing about digital calipers are those stupid-small batteries that don’t last 5 minutes and don’t stay in too well.  Sometimes you lose the battery cover then you’re really screwed.  To find a workable solution to this issue, I googles and saw a bunch of 3D printed solutions for data cables on these calipers.  I decided that I didn’t care much for the data part, but to 3D print a connector just for this seemed a waste of time. Sure, you can find some Dupont connectors to 3D print, but is it worth it? I set about a different way.

I happen to have a large number of servo connector cables from my quadcopters days. It just so happens that one of these female 3-pin dupont connectors fit perfectly in the caliper’s data slot. And if you used male wires, bent them backwards and shoved them in the data connector slot, it holds tight and provides a great connection for the power rails.

First, get a stabby thing and take the dupont connectors off some single-wire connectors (red and black are a good choice for colors).

tools

Capture

Take out all 3 female connectors form a servo cable and shove the male wires on the two ends of the servo connector as shown. Next you want to be careful and bend the male wires around the edge. You have to make sure your orientation is correct for the pins as they need to line up red with the (+) terminal and black with the Gnd otherwise you’ll be making a new cable—ask me how I know…   I did this in 2 stages since the pins are fragile. I slowly bent them against a tabletop to 90 degrees. Assessed their quality and angles and bent the remaining excess to 180 degrees

bend90degrees 

 

When done you should have something that looks like this:

180degrees

 

Plug it into the data port and you should have good connectivity with the power rails. It is a tight interference fit.  final Product

 

I’ve considered adding this to a AAA or AAAA battery pack I could mount on top or the back of the calipers. I’m pretty busy so that might not happen. If it does, I’ll post my janky design here though.