Enabling I2C on Raspbian

This is a quick guide to enabling I2C support on the Raspberry PI operating system Raspbian. This may work on the other Linux based distros available for the Pi but I have not checked.

sudo apt-get update
sudo apt-get install python-smbus

Next we need to enable the kernel drivers for  I2C, by default the drivers are blacklisted so we must un-comment the lines that include “i2c-bcm2708”

sudo nano /etc/modprobe.d/raspi-blacklist.conf

Then add the kernel module “i2c-dev” to /etc/modules

sudo nano /etc/modules

Then finally reboot the Pi

sudo reboot

Using the I2C Command Line Tools

The i2c-tools package provide a number tools for operating on the I2C bus using the command line. The first is i2cdetect which scans the bus for devices and then prints an address map.

i2cdetect -y 1

The next is i2cset, this is a tool that allows you to set register values on an I2C device. The first argument after the bus is the chip address, then the register address and finally the value to write. All of the arguments are in decimal.

i2cset -y 1 <chip> <addr> <value>

The opposite to the set command is i2cget, this reads a register on an I2C device.

i2cget -y 1 <chip> <addr>

Another tool is i2cdump which reads out all of the registers of a I2C device.

i2cdump -y 1 <chip>
         

R2R Ladder – Part 2

I have built the R2R ladder DAC, that I had previously built on breadboard, on a piece of copper clad board. This has fixed something that I forgot to mention in the last post; which was that at the lower end of the sawtooth ramp there was a high frequency oscillation. This was probably because of the poor grounding I had when testing. In the right-hand corner of the board I built a op-amp buffer stage.

photo of the prototype R2R ladder DAC

Below is a screenshot from my Oscilloscope of the DAC in operation. As you can see it works!

oscilloscope screenshot showing the sawtooth wave generated by the R2R ladder DAC
 

An Analogue Clock in Processing

I came across some code I wrote in Processing a while ago so I thought I’d post bits of it here. I made a really simple analogue clock. Below is s screenshot of what I came up with.

I wrote a small function that handles drawing a hand of the clock. This function is called for each hand of the code by the draw loop.

void draw_hand(long count, long modulo, long len)
{
    float nx, ny;
    a = (2*PI/modulo) * count - (2*PI/4);
    nx = (width/2) + (Clock_Size/2-len) * cos(a);
    ny = (height/2) + (Clock_Size/2-len) * sin(a);
    strokeWeight(7);
    line(width/2, height/2, nx, ny);
}

Then all we need to do in the draw loop is call the function for each of the hands of the clock. Here is an example of drawing the hours hand.

To put the ticks around the outside of the clock I used the code below.

  fill(0,0,0);
  for( int i = 0; i < 12; i ++ ) {
    float angle = radians(i*30) - (2*PI/4);
    nx = (width/2) + (Clock_Size/2-35) * cos(angle);
    ny = (height/2) + (Clock_Size/2-35) * sin(angle);
    text(i == 0 ? 12 : i, nx, ny);
  }

Processing.js Version

I have got this code working fine using Processing.js. See it here

     

R2R Ladder DAC

This post is about an R2R Ladder DAC that I build one evening. I wanted to play around with the Arduino Mega 2560 board I have and this seemed like a perfect way to try it out. Below is the schematic for the DAC…

This is an 8-bit DAC built-up from just resistors, each bit is connected to a GPIO pin of the Arduino. I built the circuit on a breadboard and connected it to the Arduino using jumpers.

The first thing I did with the software is toggle the MSB bit using the Ardino digitalWrite() function, however using these functions makes writing to the DAC far too slow. So I needed to write directly to the ATmega GPIO registers and to avoid jitter I use a Timer interrupt. At the moment the software just increments PORTA each interrupt and lets it overflow, this creates a sawtooth wave on the output of the DAC and exercises each bit in the DAC.

int timer1_reload;
 
void setup() {
   pinMode(22, OUTPUT);
   pinMode(23, OUTPUT);
   pinMode(24, OUTPUT);
   pinMode(25, OUTPUT);
   pinMode(26, OUTPUT);
   pinMode(27, OUTPUT);
   pinMode(28, OUTPUT);
   pinMode(29, OUTPUT);
   PORTA = 0;
 
   noInterrupts();
   TCCR1A = 0;
   TCCR1B = 0;
 
   timer1_reload = 65535 - 5;
   TCNT1 = timer1_reload;
   TCCR1B |= (1 << CS10);
   TCCR1B |= (1 << CS11); // /644
   TIMSK1 |= (1 << TOIE1);
   interrupts();
}
 
ISR(TIMER1_OVF_vect)
{
  TCNT1 = timer1_reload;
  PORTA++;
}
 
void loop() {
}

Next I will generate a sine wave using the DAC.

   

Creating a Virtual Serial Port in Linux

When developing software that uses a serial port for communication with the outside world it is really helpful to be able to use a virtual serial port and write test code to aid in debugging. Well it turns out there is a program that does that in Linux, it’s called socat. Using this utility you can create a pair of virtual serial ports and connect them together. To install it in Ubuntu run the following commands.

sudo apt-get update
sudo apt-get install socat

Once you have the socat program installed you just need to run the following command to create a pair of virtual tty devices. When you run the program it will print out which ports you need to use.

socat -d -d PTY,b57600 PTY,link=ttyVS1,b57600

This is an example of the output that socat produces. The two ports it has created are /dev/pts/5 and /dev/pts/6. These can vary from time to time so keep an eye on that.

2013/11/15 07:47:13 socat[2970] N PTY is /dev/pts/5
2013/11/15 07:47:13 socat[2970] N PTY is /dev/pts/6
2013/11/15 07:47:13 socat[2970] N starting data transfer loop with FDs [3,3] and [5,5]
   

Notes on Implementing a Timer

I’m currently working on a project at work that includes a timer that will turn relays on during certain time periods and off outside them. The timer wasn’t nearly as easy as I thought it would be so I decided to prototype the code on the PC as it’s a lot easier to debug than on a tiny little PIC18F. All of the code in this post will be in C# which I what I used to prototype with.

The weird thing about this timer is that the day is assumed change at 3am and not midnight. So a day starts at 3am and ends at 2:59am, this is apparently so that the relay can be on across midnight. This caused massive confusion and I struggled to implement it.

The idea is that the timer will store and work with an internal representation of time and then convert to hours/minutes only when displaying settings to the user and when getting the time from the RTC. This internal representation is a single integer number of minutes from midnight offset in such a way that times less than 03:00am are offset by a day. This means that 03:00am is 180 minutes as you would expect but 02:55 is actually 1615 minutes. Using this representation means that comparing time is really easy and that makes the whole timer and user interface much easier to implement. Below are some constants

const int MinutesPerDay = 1440;
const int MinInternalTime = 180;
const int MaxInternalTime = 1619;

Below is a function that converts hours and minutes to the internal representation. If the time is less than the minimum internal time then it’ll add a whole day to the time.

int TimeToInternal(int hrs, int min)
{
    int time = hrs*60 + min;
    if( time < MinInternalTime) {
        time += MinutesPerDay;
    }
    return time;
}

Next I needed a function to convert the internal representation to actual time, in hours and minutes. Here the time is returned as a tuple of two integers, in the C version I used two pointer parameters instead.

Tuple<int, int> InternalToTime(int time)
{
    if( time > MinutesPerDay ) {
        time -= MinutesPerDay;
    }
    return new Tuple<int, int>(time/60, time%60);
}

I have also implemented a similar timer elsewhere in the project, but it was much simpler and the day changed at midnight as you would expect. This is the code I used to implement the timer that turns on a feature during a time period, then turns off. This period can span across midnight. The time is really simple, just multiply hours by 100 then add the minutes so 11:32 is 1132.

bool IsInPeriod(int time, Period period)
{
    if( period.Start < period.Stop ) {
        return (time >= period.Start) && (time <= period.Stop);
    } else if ( period.Start > period.Stop ) {
        return (time >= period.Start) || (time <= period.Stop);
    } else {
        return false;
    }
}

Here is the Period class as I implemented it, nothing special or interesting here

public class Period {
    public Period() {
    }
     
    public Period(int start, int stop) {
        this.Start = start;
        this.Stop = stop;
    }
     
    public static int HrsMinToInt(int hrs, int min) {
        return hrs*100 + min;
    }
     
    public int Start { get; set; }
    public int Stop { get; set; }
}

Sorry if none of this make any sense, this post has mostly just been a brain dump so that if in the future I work on this again, or something similar I can remind myself of all this.

       

Creating a really simple Biconvex-like Lens in POVRay

I created a macro that will generate a really simple Biconvex lens. The macro take in three arguments, Location, Radius and Overlap. It works by taking the intersection of two spheres. The resulting object is then translated to wherever you want it to go in your scene.

#macro Make_BiconvexLens(Location, Radius, Overlap)
    intersection {
        sphere { <0,0,0>, Radius translate <0,0, -R/Overlap>}
        sphere { <0,0,0>, Radius translate <0,0, R/Overlap>}
        texture { T_Glass3 }
        interior { I_Glass }
        photons { reflection on refraction on }
        translate Location
    }
#end
       

Building RTLSDR and GNURadio

I recently brought a USB DVB-T dongle that is based on the Realtek RTL2832U chip which, with RTLSDR, can be used as a really low cost SDR. This is because it can be setup to return the raw I/Q samples to the host PC.  Once you have the samples they can then be processed, I tend to use GNURadio for the processing.

There is a script available that downloads and installs everything, RTLSDR, GNURadio, and more. I recomend you try it first. I think there is also a new project from the GNURadio people that will automate building and installing. I had had some issues with building gr-audio when I wrote this so I use the manual method of building the code for now.

First of all make sure you have all of the dependencies GNURadio has, see http://gnuradio.org/doc/doxygen/build_guide.html for a list of them.

Once you have made sure you have all of the libraries that GNURadio needs you can build the code.

mkdir build
cd build
cmake ../
make && make test

sudo make install

This whole process can take a while to complete. On my work machine it took nearly 40mins! I had an issue building the gr-audio on my laptop that I still haven’t been able to resolve.

Next I built downloaded and extracted the RTLSDR source code. As with GNURadio we need to create a build directory and run cmake.

mkdir build
cmake ../
make

Then I ran a few commands to check that the code and the dongle worked correctly. The first tests to make sure samples are being returned at the correct rate and the second will receive and demodulate a WBFM station.

rtl_test
rtl_fm -f 97.1e6 -W -s 1000000 -r 48000 – | aplay -r 48k -f S16_LE

And that’s it! Now I’m going to play around with GRC and sound card I/O.

       

Contolling the CPU Governor in Linux

Recently I wondered how you control CPU throttling in GNU/Linux systems so after doing a little research this script is what I’ve come up with. It’s based on some others that I’ve come across. All it does is set the CPU throttling mode to “performance” then displays the current CPU frequency setting, which should be full speed.

#!/bin/sh
for CPUGOV in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
do
    echo -n performance > $CPUGOV;
done
 
# Display Stats about new settings
grep -E '^model name' /proc/cpuinfo | head -n 1
for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
do
    cat  $CPUFREQ | awk '{ print $1 / 1e6 "GHz"; }'
done
 
exit 0
     
1 2 3 4 5