Artificial Intelligence – 1. Perceptrons

The simplest form of artificial intelligence

Perceptrons are a probabilistic model for information storage and organization within the brain.  They can be trained to classify linearly separable patterns.  Perceptrons can be organized into a MISO (Multiple-Input, Single-Output) “feed-forward” network that takes in binary inputs and gives binary outputs.  A single perceptron is shown below.

Simple Perceptron Model

In the model, x_0 , x_1, ..., x_n are individual inputs (from outputs of other neurons or from direct input), w_0, w_1, ..., w_n are weights, b is the bias, \nu is the output from the perceptron before the activation function, and y is the final output from the perceptron.

The output of the perceptron is calculated by adding each of the inputs times the input’s weight, along with the bias. \nu = (x_0*w_0) + (x_1*w_1) + ... + (x_n*w_n) + b.  This value, \nu, is then passed through the activation function to find the final output yy = hardlim(\nu).The activation function for a simple perceptron network is usually the hardlim() function, which outputs 1 if the input is positive and 0 if the input is negative.

Hardlim() function

Alternatively, the hardlims() function can also be used as the activation function, which outputs -1 if the input is negative and 1 if the input is positive.

The output of the perceptron can be calculated in matrix format:

Note that the X matrix needs the 1 in the first position to multiply the bias.  This could be -1 if desired, but unnecessary because the bias b can be positive or negative.

Logic gates with perceptrons

A perceptron can act as logic gates.  For example, a 2-input perceptron can act as an “and” operator with the following weights: w_1 = w_2 = 0.5, b=-0.75.

1-Neuron perceptron neural network acting as AND gate.

This network is even fault tolerant – input values do not need to be exactly 0 or 1.

Fault tolerance of AND perceptron

The output of the perceptron can be graphically displayed as below.  The horizontal axis corresponds to input x_0 and the vertical axis corresponds to input x_1.  The outputs are plotted in their proper x_0, x_1 coordinate and displayed as 0 or 1.  Any combination of inputs will fall in the shaded areas needs an output of 1, while any other combinations need an output of 0.  Because there exists a line between on which the output classes can be separated, the inputs and outputs are linearly separable.  Note that the equation for the decision boundary is w_1*x_1 + w_2*x_2 + b = 0.

Plot of perceptron inputs and outputs.

Multi-layer networks

A single-layer perceptron can only classify into 2 classes that are linearly separable.  A multi-layer network is needed for patterns that are not linearly separable.  These multi-layer networks contain a hidden layer.

Multi-layer feed forward perceptron neural network.

These multi-layer networks can be used to classify inputs more complexly.  Take the XOR function – it is linearly inseparable and needs a hidden layer.

The network is able to classify the linearly inseparable inputs by mapping the “input space” to a “feature space” of the hidden layer.  The feature space from the output neuron (Neuron 5) for the XOR gate is shown below.


Writing files to Nucleo PYB Flash

After flashing MicroPython to your Nucleo board, and working with REPL, the next step is to write your Python program and transfer it to the board.  The STM Nucleo boards do not come with a USB-OTG (USB On-the-go) connector, so it is not possible to directly access the PYB flash directory where python scripts and programs are stored.  The STM Discover boards have this connector built in, and it is possible to mimic these boards’ USB-OTG circuit with the Nucleo through the GPIO Pins.  This process, however, requires a higher level understanding of electronics and requires additional hardware.

It is possible to access the PYB Flash directory using a serial interface through the ST-Link programmer’s USB port with a program called ampy – Adafruit MicroPython Tool. Install instructions are found on Adafruit’s website and their GitHub page.

Before using ampy, it is important to know the communication port your OS assigned to the Nucleo board.  See instructions under “Opening REPL – Testing your MicroPython flash” to determine COM port.

All Ampy Commands

Execute the command “ampy –help” in a terminal window to see a list of all available commands.

Display PYB Flash Contents

Execute the command “ampy -p COM_PORT ls /flash” (replace COM_PORT with your communication port)

Write File to PYB Flash

In your terminal window, make sure you are in the directory of the files you are trying to push to the Nucleo board.

Execute the command “ampy -p COM_PORT put FILE_NAME” (replace FILE_NAME with the file you are pushing).  Use the “ls” command as document above to ensure that the file was correctly sent.

Remove Files and Directories from PYB Flash

Use the command “ampy -p COM_PORT rm FILENAME” and “ampy -p COM_PORT rmdir DIRNAME” to remove files and directories, respectively, from PYB Flash.

Other Functions

Use “ampy –help” for a list of all functions.  Read the ampy GitHub Readme for even more information.

Controlling an LED with MicroPython

Powering an LED with a MicroPython embedded board is extremely easy with only a few lines of code.  This can be achieved using the REPL or by writing code to  In this example we will use the REPL to turn on and off the LED, as well as change the brightness using pulse width modulation (PWM).

Circuit Schematic

The anode of a the LED is connected to a 100Ω resistor and then connected to one of the Analog GPIO pins of the microcontroller.  The cathode of the LED is connected to a ground pin of the microcontroller.  In the example below, the LED is connected to the A5 pin of a STM32 Nucleo board.

Turning the LED on/off

The LED can be turned on and off by configuring the anode pin as a digital output pin.  To do so, use the pyb.Pin() method.  The first argument to the Pin() method is the GPIO pin name, and the second argument is the pin mode.  The pin mode “OUTPUT” will configure the pin as a digital output, where Pin.high() outputs 3.3V and Pin.low() outputs 0V.  Note:  In future versions of MicroPython, the pyb module will be replaced by the machine module.

Changing LED Brightness using PWM

The brightness of the LED can be controlled by changing the voltage to the anode.  This can be accomplished using two methods: by using pulse width modulation (PWM)or by using an digital-analog converter (DAC).  For this example, we will be using PWM to accomplish brightness control.

To use PWM in MicroPython, we will need both a Pin object and a Timer object.  We must use a GPIO pin that has a timer function, this can be determined in the user manual specific for your board.  For example, with the STM32 Nucleo L476RG, the user manual is located here, and on  page 53 we can see that pin D3 has the TIM2_CH2 function.  Change your circuit to reflect this: move the anode of the LED to Pin D3.

Now we can create the Pin and Timer object to control the LED.  Reset your microcontroller, and enter the following into the REPL.  You can determine the correct timer number and channel number from the data table.  Recall, we are using Pin D3, which has function TIM2_CH2: Timer 2 Channel 2.  With the channel.pulse_width_percent method, you can enter a PWM percent between 0-100.


Flashing MicroPython to STM32 Nucleo

In Windows

MicroPython can easily be run on any of the compatible STM32 Nucleo boards listed by flashing the newest version to the board using the ST-Link program.  A list of compatible boards can be found at the bottom of MicroPython’s download page under “Firmware for other boards”.  However, the dfu files listed on this page cannot be natively flashed to the Nucleo board; rather, a hex file must be built and compiled from the MicroPython source code.  The process to do this is quick and easy, and should take only a few moments.  For this tutorial, a new Nucleo-L476RG will be flashed with the newest version of MicroPython.

In order to simplify the process, we will be using the Windows version of the ST-Link software to flash the built MicroPython image to the Nucleo board; however, it is tremendously easier to build the hex file using a unix-based operating system.  For the purpose of this tutorial, we will use a Debian virtual machine to do this; however, any unix environment will work (unix servers, Raspberry Pi, etc.)   Note:  It is recommended to use either Debian or Ubuntu as the linux distro.  Other version will work but the procedure may differ from this tutorial.

Create and configure a Debian VirtualBox virtual machine

  1. Install the most recent version of Debian Linux to a VirtualBox virtual machine.  There are countless online resources documenting this procedure.  For further info, read here.
  2. Log into unix.  Open a terminal window.  Enter the following commands one by one into the terminal window.  Press enter/return after each command, and wait for the {your-user-name}@debian or root@debian prompt between entering each command.  Replace {your-user-name} with the username you chose during installation.  Note:  Instructions preceded with >>> are notes, not commands to be entered.

Building MicroPython for your Nucleo board

All pre-requisite packages and software should now be installed, and you can clone the MicroPython source.  Enter the following commands into the terminal. When entering the last make command, a list of supported boards to replace {your-board-model-here} can be found here, the directory names are all valid board types.  Use no spaces and all caps.  See images below.

Upon success, the terminal should display the following “LINK build-NUCLEO…” message:

If you have this message, you have successfully built MicroPython for your Nucleo board!

Copying files from VirtualBox virtual machine to host

We need the firmware.hex file that was built in unix on a Windows PC.  If you built MicroPython on a dedicated unix computer or did not use a VirtualBox virtual machine, the following steps do not apply and you must find a way to copy firmware.hex to your Windows PC.  The following procedure documents copying the firmware.hex file from a VirtualBox virtual machine to the Windows host.

  1. Right click the network icon on the bottom right corner of the VirtualBox window and select “Network Settings”.  See highlighted image below.
  2. Select “Host-only Adapter” from the drop down menu next to “Attached to”.  Click OK.
  3. Open a terminal window in Debian.  Type “ip address”.  Write down the IP address under “link/ether” after “inet”.  See image below.  IP address from image below is
  4. Minimize (but do not close) VirtualBox.  In Windows, open your favorite FTP client (I recommend FileZilla Client).  In the FTP Client, enter the IP address from the previous step as the host, your unix username and password as the FTP account, and use port 22.  Note:  If your FTP client does not allow you to specify port number, enter sftp://{your-ip-address-here} into the host field.
  5. In the FTP client, navigate to micropython/ports/stm32.  You should see a directory named “build-{your-board-model-here}.  Open this directory.  Browse for “firmware.hex”.  Copy this file to your Windows desktop.
  6. You can now close VirtualBox.  We no longer need Unix.  In fact, you can delete your virtual machine if you wish.  IMPORTANT:  If you plan to use your virtual machine again, repeat steps 1 and 2 but change “Host-only Adapter” back to “Bridged Adapter”.

Flashing MicroPython firmware HEX file using ST-Link

The hard part is done, and now we must use the ST-Link software from ST to flash MicroPython to our board.

  1. Download and install the STM32 ST-Link Utility software.  It can be found on ST’s website here.
  2. Connect your Nucleo board to your computer using a mini USB cable through the STLink programmer port.  Allow drivers to install in Windows.
  3. Open the ST-Link software.  From the top bar, Select File>Open.  Browse for your firmware.hex file.  Click OK.
  4. From the top bar, select Target>Connect.
  5. From the top bar, select Target>Program & Verify.  Leave default settings, click Start.  If successful, you will see “Verification… OK” at the bottom status window.  You can now close ST-Link Utility.

You have successfully flashed MicroPython onto your Nucleo board!!!

Opening REPL – Testing your MicroPython flash

We can communicate with MicroPython through the ST-Link programmer mini-USB port using serial communication.  To do so, we will need to determine the COM port that Windows has assigned to the board, and we will need a serial client for Windows.  I recommend and will be using PuTTY as the serial client.

  1. Download and install a serial communication client such as PuTTY.
  2. Open the Windows Device Manager.  (WIN + R, type “devmgmt.msc”, press Enter)
  3. Expand “Ports (COM & LPT).  Look for the STLink Virtual COM Port entry and record the COM port.  (COM9 port below).  Close Device Manager.
  4. Open your serial client (PuTTY).  Select “Serial” under Connection Type.  Enter the COM port you recorded into the Serial Line field.  Enter 115200 for speed.  Click Open.
  5. Click inside the empty serial terminal window.  Press the RESET button on the board.  You should see the REPL display.  Try entering the command print(“SUCCESS”).

Congratulations!  You have successfully flashed MicroPython onto your Nucleo microcontroller board.

3D Printing – Improving Print Quality with Simple Modifications

Maximize 3D Printer Performance

There are several factors that play a role in the performance and quality of 3D printed parts.  A properly configured and maintained printer is an integral part in producing strong and high quality prints.  Below is a non-exhaustive list of things to look out for in order to guarantee the highest performance from your printer.

Axis Leveling

Z-Axis Squaring

On printers that use two independent steppers for the Z-axis, such as Prusa i3 model printers, it is important to ensure that the Z-axis is square before attempting to level the print bed.  Otherwise, first layer can occur when printing, and it can be impossible to correctly level the bed.  Use the following process to square the Z-axis:

  1. Power off the printer.
  2. Manually turn the Z axis threaded rods (lead screws), turning both at the same time and same rate, until both sides are firmly seated against the top Z axis end stops.
  3. Power on the printer. Home all axes.
  4. Re-level the print bed.

Build Surface:


It’s a well known fact that it can be a pain to level a printer’s print bed.  That said, for some plastic types a level build plate is the difference between a part printing successfully and a part detaching halfway through a long print.   Aside from reading about the importance of maintaining a level print surface, here are some tips to help level a tricky bed:

It is very common for a metal print bed to become warped over time, especially with heated beds.  This problem can be remedied by affixing a borosilicate glass plate, 3mm thick minimum, atop the metal bed.  The glass plate can be assumed to be ultra-flat, and will solve any leveling problems caused by an uneven metal print bed.  Simply secure the glass to the metal bed using binder clips.

For heated metal build beds, silicone thermal pads must be used to allow the heat from the heated bed to transfer to the glass plate.  Most thermal pads come in sheets and must be cut to size.  Use a checkerboard pattern of 1 square inch thermal pads between the metal bed and the glass plate.  For badly warped metal beds, it may be necessary to only use thermal pads in corners to elevate the glass plate above the warped metal bed.  When using thermal pads, it is unnecessary to secure the glass using binder clips, the thermal pads do a well-enough job at securing the glass.

Heated build bed with borosilicate glass plate on top. Silicone thermal pads are used between the two plates to allow heat transfer.  For relatively level metal build plates, a checkerboard pattern can be used for the thermal pads.  For badly warped metal build plates, only use thermal pads in the corners.

*Note: Some materials will damage borosilicate glass, such as PET-G.  PLA and ABS should have no problem.

Build Surface Material

Many users fuss around with painter’s tape, glue, and hairspray to increase bed adhesion.  However, a sheet of PEI makes an excellent build surface for both heated and unheated beds.  Secure the PEI sheet directly to the heated build bed using binder clips.  For the best possible performance, use PEI in conjunction with a glass plate (and thermal pads).  Adhere the PEI sheet to the glass sheet using 3M 468MP adhesive transfer tape.

High-performance 3D printer build bed.

*It may be necessary to raise the Z-limit switch when modifying the build plate.

Printer Rigidity:

Rigidity plays a huge role in the accuracy and precision of any CNC machine, such as a 3D printer.  3D printers require extreme accuracy,  thus, if they are prone to flex, the quality of prints diminishes quickly.  Below demonstrates the importance of a rigid system:

Importance of 3D printer rigidity.  Both printers are structurally identical, the first constructed of wood and the second constructed of metal.  The metal frame is significantly more rigid than the wooden frame.

Problems can arise with printers such as the one below where the Z-axis does not have proper support.  This is a common problem with Wanhao Duplicator i3’s and their clones (Monoprice Maker Select, etc.)  When the build plate moves, vibrations travel through the frame and shake the Z-axis.  For taller parts, this vibration is amplified and can lead to layer-shift problems.  These problems are resolved on printers with a more rigid frame, such as below.

Z-axis is prone to shaking.

A more rigid frame prevents Z-axis shaking.

Z-Brace Mod

A modification can be made to printer’s without sufficient frame rigidity.  A “Z-Brace Mod” will solve all problems related to frame rigidity, and it is inexpensive and easy to implement.

Wanhao Duplicator i3 clone (Monoprice Maker Select V2) with Z-Brace mod.