Monday, 9 February 2015

Arduino how to: Cheap eBay OLED Screens

Introduction

I noticed keenly priced OLED screens started appearing on eBay a long while ago.  I bought a few, but at the time there wasn't much information on how to drive them.  I found a C library on a Chinese website that I was able to cajole into MikroC for the PIC microprocessors but it was never really useful as I didn't implement any fonts.  Time has moved on and now there are a few well executed drivers out there.  I have tried a couple of different ones and this is a writeup on the approach that worked for me on the Arduino.


What is it, why would I want one?

The OLED screen is a very crisp 128 x 64 pixel mono screen.  The ones I buy have 16 rows of yellow pixels at the top and 48 rows of blue pixels at the bottom.  They are really good for giving feedback about what is happening in your Arduino code and little projects like this Arduino watch:

Time / Date / Temperature and Compass module

Buying the OLED Screen

There are a variety of similar screens available from Adafruit, if you need something other than 128x64pixels or feel more comfortable dealing with a UK supplier take a look at them.  Here is a different layout of OLED i2c sceen from Adafruit through Pimoroni.


I buy them from eBay, not only are they cheap but it's very easy.  Search for 'Arduino OLED i2c'.  The cheapest price currently is £2.57 posted from China.  I have bought 10 screens this way and so far they have all arrived working.  At that price you can afford to buy one more than you need perhaps.

There are also SPI versions available, SPI and i2c are different communication standards used to communicate between electronic devices.  This write up is about i2c screens.  (Adafruit do a driver for SPI driven screens which I believe works with the SPI eBay screens but I haven't tried this.)


Wiring it up

The i2c communications uses 2 wires.  One for Data and one for a Clock.  These pins can be found on the pinout diagram for an Arduino as SDA for Data and SCL for clock.  Just add 5v power and you are ready to go.

This is the pinout for an Arduino UNO

Connect the OLED screen to your Arduino as follows:

SCL goes to SCL
SDA goes to SDA
Vcc goes to 5v
GND goes to GND

It is that simple!



Lots more information

A slightly different device but the information here is mostly applicable:  http://www.geekonfire.com/wiki/index.php?title=I2C_OLED_Panel(128x64)



Getting and installing the library

This is the best library I have found and it works very well for me.  As well as line and basic shape drawing you get two font sizes and a bitmap editor.

To download the library:

Go to the resources of the link above.  Direct link: http://www.geekonfire.com/wiki/index.php?title=I2C_OLED_Panel(128x64)#Resources

Click on the link for the Arduino library to download it.


I recommend the automatic library installation in Arduino, which is explained here:  http://arduino.cc/en/Guide/Libraries



Once you have installed the library your Arduino environment should have these menus available (I have just upgraded to Arduino 1.6.0 which came out today!).

The GOFi2cOLED Library showing as installed


GOFi2cOLED files added to the Examples


Firing it up!

The best way to start is to look at the Examples supplied. Load up an example you like the look of from the File > Examples > GOFi2cOLED menu and upload it to your Arduino.

Oh no, it didn't work!

It might not work straight away.  In i2c you can have many different devices on the communications bus and each device needs an address.  The library assumes the address of your OLED screen is 0x3D, so far all of the screens I have bought have had an address of 0x3C.

You might need to change the i2c address used, look at the void setup() section of code:

  
Change this:

  //default address is 0x3D.
  GOFoled.init(0x3D);

To this:

  //address changed to 0x3C.
  GOFoled.init(0x3C);

And re upload the code.


Success!

Animated heart sketch running on my Arduino UNO


If your screen still doesn't work, double check the wiring and try downloading a sketch that will sniff the i2c addresses and show you if the screen is correctly attached to the i2c bus and what address it is showing as.  Simply put that address into the code and you shoild be good to go.














Wednesday, 4 February 2015

Saturday 30th January

Well lots for folk at the makerspace this morning including Mike H, Mike 2, Joe, Arthur and son, Richard, Kieran, Phyllis, Les, Nathan, Sharon and a couple of folk whose names escape me, oh and me Tony.

I spent quite a bit of the morning progressing the rebuild of the 3D printer and by the end of the morning had got this far.




As you can see quite some way to go before we will be printing our first object.

The others were all doing something interesting relating to arduino coding but someone else will have to fill in on that.

Saturday, 17 January 2015

Work (re)starts on the 3D printer

Attending:- Mike, Joe, Tony, Les, Michael(2), Richard, Arthur, Elizabeth, Susan, Phyllis, Kieran


We were donated a 3D printer in need of some TLC last year. 
Details of the printer here, :-
http://blackpoollug.blogspot.co.uk/2014/10/makerspacefy1-and-3d-printer.html

Donald started the ball rolling in October by refitted the filament drive motor and also re-aligned the the other drive belt. Description of the work is here:-
http://blackpoollug.blogspot.co.uk/2014/10/makerspacefy1-robots-and-3d-printers.html

Various other small adjustment have been made since, including relocating and aligning the two vertical drive motors.

Today, Tony and Les decided that they wanted to experience building the 3D printer from scratch, this entailed dismantling the printer back down to it's component parts. Here they are discussing if they have enough boxes to put all the bits in before they start.


This is what our 3D printer looks like now.


Meanwhile, Mike continues work on his electric motor project


Arthur and Joe discuss RethinkDB


Elizabeth and Susan still trying to discover why the missing Pinterest button appears  and disappears . There is a long discussion on the mailing list about this.


Gaming talk



This event was powered by coffee and Jaffa cakes.








Saturday, 10 January 2015

2015 #1 - A Chromebook a smartwatch and a windows tablet

Attending This week: Mike, Jack, Chris, Joe, Les. Keiran, Ricky, Arthur, tony, Mark and Mike(2)

A very windy day in Blackpool today. 
Elizabeth and Susan decided not to risk the journey in the little smartcar.



Jack takes a break, Mike looks at the possibility of rewinding an electric motor for a very specific role.



Multiple and diverse discussions around the table.
 There was a lot to talk about following the Christmas / New Year break.



Chris showed off his new Chromebook, and explained how to get Ubuntu on it.



Then Chris demonstrated a smartwatch 


Arthur 'upgraded'  his windows laptop to dual boot with Linux Mint, with the help of Tony.

Les showed off a 7" windows 8 tablet obtained for the bargain price of £60
Attempts to get Linux on it are ongoing.




Sunday, 4 January 2015

Temperature monitoring display using old Android tablet

My home temperature monitoring project moved on another step with the addition of this  old Android 2.3 tablet used to display the current temperatures around the house. Two downloads from the app store were needed,  Stay awake , and Web reloader .  One keeps the screen permanently on, and the other one  is needed to refresh the page regularly to update the temperatures. 



I started this project several years ago, and this post shows the original stripboard arduino/shrimp and 433 tranceivers 

Later, I switched to using separate transmitters and receiver like these:-

And these are the Dallas DS18B20 1-Wire Digital Thermometer temperature sensors:-

This is a later version of the temperature transmitter which is battery powered by 4 rechargeable AA batteries. The circuit board is sitting on top of the battery holder.


An overview of the project so far.

There is one standard arduino uno fitted with an ethernet shield and a 433 receiver, this is the gateway.  The Gateway receives the temperatures from the transmitters, and forwards the temperatures to Xively (used to be called cosm, then pachube) . The android tablet is displaying the xively web page. Next up,  add a raspberry pi to do data logging and a web server to replace xively.

So far, all I have is monitoring, and the next major step forward will be control.
Recently, I have been experimenting with turning electrical appliances on and off using the pi with the 433 transmitter mentioned above, and these radio controlled power sockets:-


The on/off signals produced by the remote control have been decoded, and can be reproduced by the pi, and sent via the 433 transmitter. A basic web page with buttons that mimic the layout of the remote control is used to turn the switch on and off. This will be the subject of another post.

Happy new year to all.






Saturday, 3 January 2015

i2c working and noisy sensors

i2c working!

I had tried many things to get basic i2c working on my RasPi B+ and despite lots of help, failed miserably.  I bought an A+ for another project and got i2c working straight away.  There are lots of tutorials on i2c on the Pi and a really good script that I mentioned in my last post so I won't be going into setting up i2c.

The test that shows whether you've been successful is running sudo i2cdetect -y 1 and having i2c components you have connected to the RasPi appear:

i2cdetect discovering my compass and gyro/accelerometer devices. (The device at UU is related to the Pi)
In the screenshot you can see that I am using the latest Raspbian image that was released last month.

I updated my RasPi B+ to the latest image and on a whim tried i2c on it and it worked!  I had thought I'd fried the i2c hardware, but I guess now that I had somehow broken something in the image, can't think how or what, but anyway refreshing the Raspbian image fixed it.

Cheap i2c devices from eBay

So the two i2c devices I have connected to my Raspi are a Compass and Gyro/Accelerometer.  Both are really cheap units.  I got the Gyro from a UK supplier because I didn't want to wait for it to come from China.

This text is what to search for if you wish to buy these and link to the actual items I bought on eBay


Both units can be bought for about a quid from China, which is amazing value for such interesting modules.


My new Raspi A+ hooked up to i2c Compass and Gyro/Accelerometer
The image above shows the units connected up, in both cases you simply need to connect v3.3, Ground, i2c Clock and i2c Data.  Nothing else to do, it couldn't be easier. Both of these units work at v3.3.

There are wires and buttons at the back of the breadboard where I was playing with the internal pull up and pull down resistors on the RasPi GPIO.

Python and Tkinter interface



As a learning exercise I put together a Python and Tkinter interface to display the output from the sensors.  I found that to get the Tkinter to work well on the Pi I was better off using Python 2.7 which was really disappointing.  

I originally wrote my own Python class to encapsulate the compass module but the results seemed iffy so I found a class that is better than my effort here: https://github.com/rm-hull/hmc5883l as it turns out, the problem is that the area of my desk where I am testing the compass is awash with magnetic interference, which I proved with my trusted Silva compass I use for hiking.  In fact the output from the compass sensor is just as iffy with the better code.

Looking at the interface, I have created a canvas in Tkinter and draw a yellow line for the compass heading and move red and green circles around for the gyro and accelerometer.

I only take notice of 2 out of the 3 data axis that the sensors give, this leads to inaccuracies in the compass if it is not kept horizontal, these inaccuracies can be fixed in code by doing the math in 3 dimensions.

The video shows just how noisy the data is.  To the point that it's difficult to interpret if the Gyro is working properly at all.

My balancing robot has 3 accelerometers on it and I have been working on the Python code (the robot has a micro Python board in it) to get a very smooth and fast accelerometer reading of tilt (by measuring the acceleration due to earths gravity) and I need to work out how to clean that up when the robot is falling and there are accelerations due to actual movement.  I have moved the accelerometers as close as possible to the wheel axis to minimise the unwanted effects of movement but there are a few challenges.  The video shows nicely what we are up against using cheaper sensors for our small scale robotics.








Monday, 29 December 2014

Triggering PWM with a push button on an Arduino


I was asked how to control PWM with a push button on an Arduino.  I thought I'd blog it and then I can link them to this post.

Heres my setup:
Under the skull printed paper circle is a brushed DC motor that used to operate the tray on a CD-ROM drive.

Heres the fritzing drawing of it
Note that usually you'd use something like the Arduino motor shield to control a load like a motor with an Arduino, here we are ok because we are just spinning the motor with no load on it.  The danger is that a motor could draw more current through the Arduino than it can handle.


This is my code. 

int pinButton = 13;        // Pin 13 is handy as it has an LED on the Arduino board attached to it
int pinPWM = 11;           // Pin I am using as PWM output to power the motor directly
int iPWMValue = 53;        // This constant value controls the speed
boolean bReleased = true;  // Used to ensure the user must release the button fully before pressing again

void setup() {
  // Nothing to setup

}

void loop() {
  if ((digitalRead(pinButton) == HIGH) && (bReleased == true)) {
    
    bReleased = false;              // Set the bReleased flag
    
    analogWrite(pinPWM, iPWMValue);  // Start PWM output to turn the motor 
    delay(55);                       // How long the PWM signal will be sent to the motor       
    analogWrite(pinPWM, 0);          // Stop the PWM /motor from turning
  }  
  
  if (digitalRead(pinButton) == LOW) {
    bReleased = true;                // Reset the bReleased flag now the user isn't pressing the button
     
  }  

}

(( mmmmm.... white space however I want it and braces.... :p ))
(Apologies to Mike Hewitt who I know doesn't particularly like comments at the ends of lines of code!)


The code uses the boolean variable bReleased to ensure that once the button has been pressed it has to be released before being pressed again.  The motor just turns a set amount each time the button is pressed and holding the button down doesn't make the motor continuously rotate.

The amount the motor rotates is set by the delay(55) in between the code that starts and finishes the analogWrite (which is what starts and stops the PWM output). So as this delay is between the PWM output starting and stopping it controls how long the PWM output is actually on for.   I found the number 55 by trial and error, trying different values until I got the effect I wanted.

The iPWMValue (53) is defined at the top of the code and used like a constant. A constant is just like a variable except whereas you can expect the value of a variable to change, the value of a constant stays, well, constant.  The reasons you would code like this are for readability and also if you were using the iPWMValue in several places and wanted to change the value you only need to change the value once in one place for that new value to be used everywhere.  Whereas if I had used the value 53 everywhere its harder to follow what the 53 means and if I needed to alter the value I need to find every place I'd used 53 and change it manually.  

The iPWMValue is passed into the analogWrite command to set what part of the PWM cycle is on.  The larger the value the more power is output and the faster the motor will turn. Please take a look at the Arduino PWM tutorial for a better explanation of PWM.    

I got to the value of iPWMValue by trial and error in combination with the delay(55) value to get the effect I wanted on video.  In practice you'd probably use a motor with a gearbox on it, here the motor is driving the disc directly. What I found was that the motor didn't like being driven too slowly. If there was a gearbox it would be possible to have the motor spinning much faster whilst the actual disc would rotate at the desired slower speed.

Here is a video of the the project doing what it does: