A minimal LCD (HD44780) library for MicroPython

November 25th, 2016 No comments

This post demonstrates a minimal LCD library for MicroPython, used on an ESP8266. This is a small collection of commands that I put together (mostly ported) to have simple control over an HD44780 compatible LCD. There are a couple of existing LCD libraries for MicroPython so make sure to check them out first, since this is a minimalistic approach and may be limiting for you project. The post is merely a reference to the code rather than full explanation on how HD44780 LCD works. There are plenty of sources about that as well as the post of the code’s original author.

I am using the NodeMCU board so make sure to adjust the connections according to the board you are using. The LCD uses an 8-bit data bus but it also supports 4-bit mode. That means we can break a byte to two nibbles (4 bits) and save up 4 wired connections.

Let’s take a look at the code. Credit goes to Matt Hawkins over raspberrypi-spy.co.uk who is the original author of the code. I just ported it over to MicroPython and made a couple of simple changes.

import machine
import time
 
LCD_RS = 16
LCD_E = 5
LCD_D4 = 4
LCD_D5 = 0
LCD_D6 = 2
LCD_D7 = 14
 
LCD_WIDTH = 16
LCD_CHR = True
LCD_CMD = False
 
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
 
E_PULSE = 0.0005
E_DELAY = 0.0005
 
pin_lcd_e = machine.Pin(LCD_E, machine.Pin.OUT)
pin_lcd_rs = machine.Pin(LCD_RS, machine.Pin.OUT)
pin_lcd_d4 = machine.Pin(LCD_D4, machine.Pin.OUT)
pin_lcd_d5 = machine.Pin(LCD_D5, machine.Pin.OUT)
pin_lcd_d6 = machine.Pin(LCD_D6, machine.Pin.OUT)
pin_lcd_d7 = machine.Pin(LCD_D7, machine.Pin.OUT)
 
def main():
    lcd_init()
    lcd_string("HD44780 LCD", LCD_LINE_1)
    lcd_string("with MicroPython", LCD_LINE_2)
 
def lcd_init():
    lcd_byte(0x33, LCD_CMD)
    lcd_byte(0x32, LCD_CMD)
    lcd_byte(0x0C, LCD_CMD)
    lcd_byte(0x01, LCD_CMD)
    lcd_byte(0x28,LCD_CMD)
    lcd_byte(0x06,LCD_CMD)
    time.sleep(E_DELAY)
 
def lcd_byte(bits, mode):
    pin_lcd_rs.value(mode)
    pin_lcd_d4.low()
    pin_lcd_d5.low()
    pin_lcd_d6.low()
    pin_lcd_d7.low()
    if bits & 0x10 == 0x10:
        pin_lcd_d4.high()
    if bits & 0x20 == 0x20:
        pin_lcd_d5.high()
    if bits & 0x40 == 0x40:
        pin_lcd_d6.high()
    if bits & 0x80 == 0x80:
        pin_lcd_d7.high()
    lcd_toggle_enable()
    pin_lcd_d4.low()
    pin_lcd_d5.low()
    pin_lcd_d6.low()
    pin_lcd_d7.low()
    if bits & 0x01 == 0x01:
        pin_lcd_d4.high()
    if bits & 0x02 == 0x02:
        pin_lcd_d5.high()
    if bits & 0x04 == 0x04:
        pin_lcd_d6.high()
    if bits & 0x08 == 0x08:
        pin_lcd_d7.high()
    lcd_toggle_enable()
 
def lcd_toggle_enable():
    time.sleep(E_DELAY)
    pin_lcd_e.high()
    time.sleep(E_PULSE)
    pin_lcd_e.low()
    time.sleep(E_DELAY)
 
def lcd_string(message, line):
    lcd_byte(line, LCD_CMD)
    for c in message: # Print out the message
        lcd_byte(ord(c), LCD_CHR)
    for i in range(LCD_WIDTH - len(message)): # Fill the rest of the line with empty characters
        lcd_byte(32, LCD_CHR)
 
main()

Copy the above code in a file, for example lcd.py and then use the following command to give it a test run (assuming your port is /dev/ttyUSB0)

ampy --port /dev/ttyUSB0 run lcd.py

Here is how it should look like ūüôā

hd44780-lcd-with-micropython

I did some changes in the lcd_string function in order to support multi length strings. So what it does, it first prints the contents of the message and then fills the rest of the line with empty characters in order to delete any remains from the previous refresh.

Hope this helps you out. Let me know in the comments.

Categories: general Tags:

Flashing MicroPython on ESP8266

November 15th, 2016 No comments

This post is a summary on how to install and use MicroPython on ESP8266. MicroPython is a Python 3 implementation, optimized to run on microcontrollers. Due to resource restrictions, it contains a subset of the original standard library. Nevertheless, it allows us to use our beloved Python language and rapid prototype our projects.

First, we need to flash the MicroPython firmware. Goto https://micropython.org/download and download the latest firmware for ESP8266. At the time of writing, this is esp8266-20161110-v1.8.6.bin. Connect your ESP8266 to the USB port and figure out the port name. I am using Linux so I use dmesg. In my case, the port is /dev/ttyUSB0. If your module powers up but does not connect to a port the are a couple of possibilities. Make sure you are using a normal USB cable with data connections. In other words, make sure that your cable is not for charging only; usually the cables coming with power banks are power only, connecting only the power pins of the USB to the module. Another possibility, is that not enough power goes through to keep the connection alive. In this case, try another cable, or try connecting the cable to another USB port.

For flahsing the firmware we need the esptool.py script. Install it using pip:

sudo pip install esptool

Once the installation is finished and the module is connected, run the following command:

esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash --flash_size=8m 0 esp8266-20161110-v1.8.6.bin

and here is what it should look like:

esp8266_micropython_flashing

By the way, you can try higher baud rates if you want to speed up the process but 115200 is a safe one.

Next, disconnect and reconnect the USB cable. Check again the port name and use a serial terminal application to connect to the module which now expects 115200 baud rate communication. I use picoterm using the following:

picocom /dev/ttyUSB0 -b 115200

Press ENTER once and you will be prompted with the familiar >>> Your module is now flahsed and you can start typing away in Python. Before closing, lets see a couple of commands to see how this works. We will flash the LED on the ESP8266 a couple of times. To do this, we need to import machine in order to manipulate the values on the pins.

import machine
import time
 
led_pin = machine.Pin(2, machine.Pin.OUT)
 
def flash_led(lp):
    lp.low()
    time.sleep(1)
    lp.high()
    time.sleep(1)
    lp.low()
    time.sleep(1)
    lp.high()
    time.sleep(1)

With the above snippet, we created a function `flash_led` that takes as an argument a pin from the ESP8266 module and toggles its value. At the start, we assign pin 2 to `led_pin`. So finally, run

flash_led(led_pin)

to flash the LED on the board.

Hope this was useful to you. Let me know of your comments.

Reference: http://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/index.html

Categories: general Tags:

nRF24L01+ basic operation. My notes

November 16th, 2014 No comments

This is a brief note I am taking while reading how to operate nRF24L01+ using a microcontroller. This post is not meant to be a tutorial, but I publishing it anyway as someone might find it useful.

Connectivity

  • 3.3V (absolute max 3.6V) supply power
  • It seems that data lines are 5V tolerant (to clarify, supply power is NOT 5V tolerant)
  • SPI communication, 4 lines
    • CSN – SPI Chip Select
    • SCK – SPI Clock
    • MOSI – nRF24L01 data input
    • MISO – nRF24L01 data output
  • There is a CE chip enable pic, which activates RX or TX mode
  • Doesn’t seem I need any pull resistors on the data line. The lines will be connected directly to the microcontroller

Operation

There are 4 types of operational modes in the module, Power Down, Standby-I, TX and RX. Standby-I seems to be the ‘normal’ operating mode and you just need to switch to TX or RX to do your task. Power Down is used to save power and the trade-off is that you need about 1.5ms to go back to Standby-I.

After reset, the module defaults to Power Down mode.

Controlling the module

The module is controlled through a register which is accessed using SPI write and read commands.

SPI Commands

  • Just before starting an SPI command, the CSN should be switched from HIGH to LOW
  • As the command is shifted out from MOSI, the STATUS register of nRF24L01 is shifted from the MISO
  • SPI communication is Most Significant Bit first – Least Significant Byte first
Categories: electronics Tags:

Autoroute PCBs in KiCad offline

October 31st, 2014 No comments

Few months back, the autorouter in KiCad stopped working. KiCad was using the free online autorouter http://www.freerouting.net/ which is now not working. The author was kind enough to open-source it and you can find it in various locations in the Internet.

Now if you want to use it directly, you can use pre-compiled files. I found them in this GitHub repository, look into the binaries directory. Download the file you are interested in. Since I am working in Ubuntu I downloaded the .jar file. Then to be able to run it, you have to install Java. I used this package

sudo apt-get install openjdk-8-jre-headless

First make sure you export your KiCad board file as .dsn from FILE>EXPORT>Specctra DSN

Then run

java -jar FreeRouting.jar

Open you .dsn file and click Autorouter!FreeRouter KiCad Offline

 

 

Categories: electronics, general Tags:

KiCad (latest dev version) does not work with Ubuntu 14.10

October 28th, 2014 No comments

I installed the latest dev version of KiCad but it seems to be problematic with the new Ubuntu 14.10. The problem is that some functions like ‘Place Component’ don’t work and freeze the application. I tried both using the PPA installation method and building from source (bzr version 5233). Have you also experienced this bug? Let me know in the comments. If I get to solve this I will update.

UPDATE 30/10/2014: So it seems that the problem occurs due to the Windows Manager (Unity). I installed GNOME and KiCad now works.

Categories: general Tags:

Currency Converter in Python

November 30th, 2013 No comments

EDIT 02-Oct-2015: Code now works with the free API at http://fixer.io/

Hello everyone! Well, many times I find myself converting between EURO, USD and GBP. So I though, why don’t write a small program to do that? Of course there are many other solutions out there like but what’s the fun in that if you don’t do it yourself, right, RIGHT?

As I always do, I search and learn as I go. So first things first, I wanted this to be a program with GUI. There are a lot of solutions for that but I decided to use wxPython. I skimmed over the documentation and it was obvious that I had to spent more time that I wanted in order to do something useful. I searched for a ‘designer’ and I found one, called wxGlade. After a quick ‘sudo apt-get install python-wxglade’ in my beloved Ubuntu I was up and running in no time. Within few minutes I created the minimalistic GUI I wanted.

For the currency conversion I found some good info here and I used part of that code. I also needed to learn about threads since I wanted to fetch the exchange rates without blocking the program and again after a quick google search this was solved as well.

The little program works well and its fast. The code is below. Let me know if you like it or improve it.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# generated by wxGlade 0.6.5 on Thu Nov 28 12:44:35 2013
 
import wx
from threading import Thread
import time
import requests
 
# begin wxGlade: extracode
EUR_USD = 1
EUR_GBP = 1
USD_GBP = 1
def myfunc(i):
    global EUR_USD
    global EUR_GBP
    global USD_GBP
    # For the following 3 commands credit goes to http://www.boxcontrol.net/write-simple-currency-converter-in-python.html#.UpkVvapyQQ-
    url = 'http://api.fixer.io/latest?base=EUR&symbols=USD'
    r = requests.get(url)
    EUR_USD = r.json()['rates']['USD']
    time.sleep(2)
    url = 'http://api.fixer.io/latest?base=EUR&symbols=GBP'
    r = requests.get(url)
    EUR_GBP = r.json()['rates']['GBP']
    time.sleep(2)
    url = 'http://api.fixer.io/latest?base=USD&symbols=GBP'
    r = requests.get(url)
    USD_GBP = r.json()['rates']['GBP']
 
t = Thread(target=myfunc,args=(1,))
t.start()
# end wxGlade
 
class MyFrame1(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame1.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.EUR = wx.StaticText(self, wx.ID_ANY, "EUR")
        self.tc_EUR = wx.TextCtrl(self, wx.ID_ANY, "")
        self.USD = wx.StaticText(self, wx.ID_ANY, "USD")
        self.tc_USD = wx.TextCtrl(self, wx.ID_ANY, "")
        self.GBP = wx.StaticText(self, wx.ID_ANY, "GBP")
        self.tc_GBP = wx.TextCtrl(self, wx.ID_ANY, "")
 
        self.__set_properties()
        self.__do_layout()
 
        self.Bind(wx.EVT_TEXT, self.eh_EUR, self.tc_EUR)
        self.Bind(wx.EVT_TEXT, self.eh_USD, self.tc_USD)
        self.Bind(wx.EVT_TEXT, self.eh_GBP, self.tc_GBP)
        # end wxGlade
 
    def __set_properties(self):
        # begin wxGlade: MyFrame1.__set_properties
        self.SetTitle("CurrencyPy")
        # end wxGlade
 
    def __do_layout(self):
        # begin wxGlade: MyFrame1.__do_layout
        grid_sizer_1 = wx.GridSizer(3, 2, 2, 2)
        grid_sizer_1.Add(self.EUR, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
        grid_sizer_1.Add(self.tc_EUR, 0, 0, 0)
        grid_sizer_1.Add(self.USD, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
        grid_sizer_1.Add(self.tc_USD, 0, 0, 0)
        grid_sizer_1.Add(self.GBP, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
        grid_sizer_1.Add(self.tc_GBP, 0, 0, 0)
        self.SetSizer(grid_sizer_1)
        grid_sizer_1.Fit(self)
        self.Layout()
        self.Centre()
        # end wxGlade
 
    def eh_EUR(self, event):  # wxGlade: MyFrame1.
        if self.tc_EUR.GetValue() != '':
            self.tc_USD.ChangeValue(str(float(self.tc_EUR.GetValue())*EUR_USD))
            self.tc_GBP.ChangeValue(str(float(self.tc_EUR.GetValue())*EUR_GBP))
            event.Skip()
    def eh_USD(self, event):  # wxGlade: MyFrame1.
        if self.tc_USD.GetValue() != '':
            self.tc_EUR.ChangeValue(str(float(self.tc_USD.GetValue())/EUR_USD))
            self.tc_GBP.ChangeValue(str(float(self.tc_USD.GetValue())*USD_GBP))
            event.Skip()
    def eh_GBP(self, event):  # wxGlade: MyFrame1.
        if self.tc_GBP.GetValue() != '':
            self.tc_EUR.ChangeValue(str(float(self.tc_GBP.GetValue())/EUR_GBP))
            self.tc_USD.ChangeValue(str(float(self.tc_GBP.GetValue())/USD_GBP))
            event.Skip()
# end of class MyFrame1
if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    frame_2 = MyFrame1(None, -1, "")
    app.SetTopWindow(frame_2)
    frame_2.Show()
    app.MainLoop()

Oh and here is a screenshot!

Categories: programming Tags:

Small spool holder for Mendel90

September 10th, 2013 2 comments

After I completed building my Mendel90 I was a bit disappointed when I found out that the spool I had (bought from ultimaker site) was smaller than the spool holder. So I placed the spool on my desk behind the printer and never really bothered to solve the problem. Every now and then during the printing I would manually unroll filament from the spool so I don’t stress the extruder motor.

Well a couple of days ago I was browsing the reprap forums and found a nice extension that solved (well sort of) my problem. Fellow reprapper GerdH created a neat extension design to support multiple spool holder sizes. I downloaded the .scad file, compiled it, sliced it with Cura with my settings and printed it. I had to run to the nearest hardware store and get a set of four screws with nuts. So within few hours I saw the post the spool holder was installed on my printer and its working perfectly. No more manual unrolling of filament!

During printing

During printing

 

The spool where it was meant to be from the beginning!

The spool where it was meant to be from the beginning!

 

Categories: 3D printing Tags: ,

3D printing my balancing robot

April 28th, 2013 No comments

3D Printing Fever!

Hello everyone. Did I tell you I am having a blast with the 3D printer? My god, this thing is wonderful. Is every engineer’s dream come true. Seriously. Anyway, in my last post I told you about putting together a Mendel90 reprap. Since then, I devoted some weekend time to calibrate the machine and I am really satisfied with the results.

As an engineer, my 3D printing time is focused on creating useful and functional parts, rather than something artistic like a complex shape or a small Yoda (even though I would like to print one some day). Anyway, its been some time since I decided to create a balancing robot, a project unfortunately I neglected for too long. So, this will be a nice opportunity to design my own parts and progress on the balancing robot project!

To do that, first I needed a CAD program to design my parts in. I never used a 3D CAD software before, so I went into the wild to see what is available. The features I was interested in are:

  • Run on Linux (Ubuntu)
  • Easy learning curve
  • Price below 50 Euros (or free!)

Let me tell you, there are not that many choices fulfilling the above. I ended up using¬†FreeCAD¬†and I really like it. Until now, it suits my needs, its free and works just fine on my Ubuntu. OK it is a little buggy sometimes but I don’t mind. At the beginning it was a bit difficult to understand how it works, but after I read about the¬†Part Design and¬†Constraints I quickly got the point. I have to admit,¬†Constraints¬†is something I didn’t know it existed in CAD software and after I discovered that I immediately loved it! When I get more experience with FreeCAD I will make a tutorial on the basics. I think it really deserves more visibility.

Designing the parts

When designing parts to be 3D printed on my machine, there are a few things that govern my design. First, the design must be compatible with the 3D extruding printing constraints. You must be careful of steep overhangs. Another thing are the holes. Most of the slicer software has some problem printing small holes accurate. My current calibration gives me hole accuracy 0.4mm(+/-) which is not that good but it hasn’t caused much trouble yet. However, my main concern when designing is the use of filament, for a few reasons. The most obvious one is cost. If you make a really big and heavy part, you could raise the cost to a level which 3D printing it out doesn’t make sense, if you can buy a similar part (robot chassis for example) much cheaper from the web. And keep in mind that you may make mistakes and need to reprint a part 2 or 3 times (even more?) before deciding its the one! What is more important for me though, is printing time. You see, more filament = more printing time! Most of the times I am anxious to try out my latest design and I hate to wait more than 10-15 minutes. So I tend to design, quick-to-print parts. At least for now.

Today’s print: Motor mount

Today, I designed a part used to mount the motors on the chassis. Took some specs from the motor datasheet, and designed the part so it can be screwed on the motor and hold it firmly. So I fired up FreeCAD and some time after, the result is this:

Freecad design

Freecad design

After exporting the .stl file and slicing it with Cura it was ready for printing. The pictures show the result.

Fresh out of the oven!

Fresh out of the oven!

Good alignment of the holes

Good alignment of the holes

Motor screwed on the mount

Motor screwed on the mount

Attached on the chassis

Attached on the chassis

 

Hopefully sometime within next month I will find some time to attach the motor controller and start working on the electronics of the robot.

Until next time…

Building my Mendel90

February 10th, 2013 No comments

In this post I will explain my experience building my first 3D printer. I should state that before buying this printer I knew nothing about building a 3D printer or any of the terminology. NOTHING. I was just fascinated by the technology and capabilities and followed the progress. The main reason I am writing this is to encourage complete beginners to overcome the initial doubts that they may have, as I had.
Lets start with the really basics, how it works. The first thing you need is a digital design of the object. This can be created by you through a cad software like¬†openscad¬†or¬†blender, or you can download a design created by others. So after you have this file, a “slicer” software will prepare it for printing. This software will cut the object into multiple layers, slices, horizontally. The same way you slice a loaf of bread. This software generates a code that the printer understands. The printer works by laying down melted plastic tracking the outline of the object and then fills the areas need filling. The plastic cools down quickly and solidifies. Doing the same thing layer by layer, the object is formed.

Building the machine

There is a variety of machines you can buy. I did not do an exhaustive research on the capabilities and features. My requirements were simple, the printer should be:

  • Reliable
  • Cheap
  • and Europe based to avoid any taxes

People at the reprap forums suggested me Mendel90 that was designed by nohead, an experienced member of the community, and it was at the right price and it was in UK. It turned out that Mendel90 has another great feature, that of the support both pre and after sales. Both from Chris(nophead) and Mary  were kind enough to answer all my questions clearly and quickly. The kit arrived in about a week.

The parcel arrived!

The parcel arrived!

When I first opened the parcel I was overwhelmed by the amount of parts. I really wanted to start printing but there I was in front of hundreds of small bits and pieces. But don’t worry. The included instructions provided by nophead are really detailed and guide you through. I am not saying that is super easy to build the machine. I think you need some basic skills in putting things together and some soldering skills as well. There are some easy parts and some more challenging. I messed up a part or two but fortunately I was able to fix it.

It took me about two nights (from 10pm to 8am) to finish the machine. It was a great experience. I found it to be challenging and I learned a lot about how it works. After some tests and quick calibration I printed the small android figure you see in the picture.

My first 3D print!!!

My first 3D print!!!

The code was provided by nophead. After that, the second journey began. The journey of calibration. But let’s leave that for another time.¬†I should say that this hobby requires time and patience. You will get frustrated and angry but when you manage to get the print as you intended, the accomplishment feeling is incredible. You can build your ideas into real objects… Just incredible.

I hope I gave you some basic idea what this is all about and I hope to see you in the reprap forums.

Categories: 3D printing Tags: ,

First steps in 3D printing

February 4th, 2013 No comments

Hello everyone.

About a month ago I was watching a video on youtube about a guy building a robot. At some point that guy set “…I printed these parts on my RepRap…”. Those words echoed in my head, again and again. …… and bam. That was it.

You see, I have watched the progress of 3D printers for some time now. From the moment I saw one online I was hooked. Unfortunately the price was too high for a “toy”. At least that what I was thinking then. I considered it as a “toy” since is something I don’t really need. I wanted it to satisfy my creativity itch. So I decided to bury my 3D printing desire to save some money. And I was good at it. Until it hit me when I watched that video.

Right there I decided I would buy one, no matter what. I agree that spending 600-700 Euros may seem like a lot at the beginning, but let me tell you that the rewarding you get from 3D printing is huge. Talking for myself, its been a long time since I felt that much satisfaction in my tech life experience.

So, I believe that 3D printing is going to be the new part of this blog. To get the ball rolling, my next post will describe the machine I bought and the assembling experience.